Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/visual-studio-2010/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
进程外COM服务器:BSTR未正确封送 我在Visual Studio 2010中开发了一个C++的OPROC COM服务器,以避免Shellextensions().中的64位vs. 32位问题。_C++_Visual Studio 2010_Com_Ole - Fatal编程技术网

进程外COM服务器:BSTR未正确封送 我在Visual Studio 2010中开发了一个C++的OPROC COM服务器,以避免Shellextensions().中的64位vs. 32位问题。

进程外COM服务器:BSTR未正确封送 我在Visual Studio 2010中开发了一个C++的OPROC COM服务器,以避免Shellextensions().中的64位vs. 32位问题。,c++,visual-studio-2010,com,ole,C++,Visual Studio 2010,Com,Ole,我在IDL文件中描述了如下()所示的接口: 这个文件为我生成了一个代理/存根DLL,我还注册了该DLL以使用标准封送器方法。 如果我现在打电话 IShellServerx86* pShellServer = NULL; CoCreateInstance(__uuidof(CShellServerx86), NULL, CLSCTX_LOCAL_SERVER, __uuidof(IShellServerx86), (void**)&pShellServ

我在IDL文件中描述了如下()所示的接口:

这个文件为我生成了一个代理/存根DLL,我还注册了该DLL以使用标准封送器方法。 如果我现在打电话

IShellServerx86* pShellServer = NULL;
CoCreateInstance(__uuidof(CShellServerx86), NULL, CLSCTX_LOCAL_SERVER,
                 __uuidof(IShellServerx86), (void**)&pShellServer);
服务器已创建,我可以调用该方法

HRESULT CShellServerx86::ShowFileInfo(BSTR file, BSTR* htmlFile, BSTR pathChar)
并使用创建的参数(客户端):

在客户机中,BSTR是正确生成的,但是当调用COM方法(他找到了!)并且我调试到dllhost.exe中时,参数无效,就像选择了错误的编码一样。我试图在整个项目中设置“Unicode”,但没有任何改变

我是否忘记了任何设置,或者是否应该尝试其他数据类型进行编组

提前谢谢你的帮助

编辑:

客户机的实现是:

int CShellWrapperx64Module::ShowFileInfo(IN const char* file, 
                                                    OUT VARIANT &htmlFile,
                                                    IN const char* pathChar)
{...
    ::CoInitialize(NULL);
    IShellServerx86* pShellServer = NULL
    hr = ::CoCreateInstance(__uuidof(CShellServerx86), NULL, 
                           CLSCTX_LOCAL_SERVER, __uuidof(IShellServerx86),
                           (void**)&pShellServer);
    BSTR filebstr = ::SysAllocString(A2OLE(file));
    BSTR pathBstr = ::SysAllocString(A2OLE(pathChar));
    BSTR htmlFileBstr = ::SysAllocString(A2OLE(""));
    //Call method of Server
    hr = pShellServer->ShowFileInfo(filebstr, &htmlFileBstr, pathBstr);
    ::CoUninitialize();
    VariantInit(&htmlFile);
    htmlFile.vt = VT_BSTR;
    htmlFile.bstrVal = htmlFileBstr;
}
服务器方法声明如下:

HRESULT CShellServerx86::ShowFileInfo(BSTR file, BSTR* htmlFile, BSTR pathBSTR)
{...
 //TODO
}
在服务器和客户端方法中,调试器将BSTR字符串识别为wchar\u t*-数组。但是,例如,服务器方法中字符串“file”的内容类似于:0x02546e80㤈榧".

编码适用于所有设置为多字节编码(Visual Studio)的项目(客户端/服务器)

编辑2:

服务器声明如下:

class IShellServerx86 : public IUnknown {
  public:

  virtual HRESULT ShowFileInfo(BSTR file, BSTR* htmlFile, BSTR pathChar) = 0;

};
接口的实现:

//CoClass from Interface (Implementation)
class CShellServerx86 : public IShellServerx86 {
 public:
  CShellServerx86();
  virtual ~CShellServerx86();
  //inherited from IUnknown
  ULONG STDMETHODCALLTYPE AddRef(void);
  ULONG STDMETHODCALLTYPE Release(void);
  HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppv);

  HRESULT ShowFileInfo(BSTR file, BSTR* htmlFile, BSTR pathChar);

 protected:
  ULONG m_uRefCount;
};
…和类工厂 类CShellServerx86ClassFactory:公共IClassFactory{ 公众: CShellServerx86ClassFactory(); ~CShellServerx86ClassFactory()

受保护: ULONG m_uRefCount; })

从DLL获取类方法:

STDAPI DllGetClassObject ( REFCLSID rclsid, REFIID riid, void** ppv ) {
  if (!::InlineIsEqualGUID(rclsid, __uuidof(CShellServerx86)) ) {
     return CLASS_E_CLASSNOTAVAILABLE;
  }
  *ppv = NULL;
  CShellServerx86ClassFactory* pShellServerFac;
  pShellServerFac = new CShellServerx86ClassFactory;
  if (pShellServerFac == NULL) {
     return E_OUTOFMEMORY;
  }
  pShellServerFac->AddRef();
  HRESULT hr = pShellServerFac->QueryInterface(riid, ppv);
  pShellServerFac->Release();
  return hr;

}

首先,您必须检查
A2OLE在您的案例中产生了什么,以及这是否适合输入
SysAllocString()

然后您必须实现该
//TODO
-被调用方负责正确构建out参数的值。您必须执行以下操作:

HRESULT CShellServerx86::ShowFileInfo(BSTR file, BSTR* htmlFile, BSTR pathBSTR)
{
    if( htmlFile == 0 ) {
       return E_POINTER;
    }
    // do useful stuff, generate the string for the htmlFile, then
    *htmlFile = SysAllocString( TheStringForHtmlFileParameter );
    return S_OK;
}
另外,您正在调用方中泄漏
BSTR

BSTR htmlFileBstr = ::SysAllocString(A2OLE(""));
//Call method of Server
hr = pShellServer->ShowFileInfo(filebstr, &htmlFileBstr, pathBstr);
将丢失作为第二个参数传递的
BSTR
,因为被调用方将创建新的
BSTR
。只需将其初始化为空指针即可:

BSTR htmlFileBstr = 0;
//Call method of Server
hr = pShellServer->ShowFileInfo(filebstr, &htmlFileBstr, pathBstr);

另外,由于在完成时没有调用
SysFreeString()
,因此仍然会泄漏所有
BSTR
s
在每个
BSTR
上,您拥有或最好使用像
ATL::CComBSTR
\u BSTR\u t
这样的包装类。BSTR只有一个编码,utf16。您留下了大量获得A2OLE()的机会转换错误,这主要取决于默认代码页。通过记录您如何得出编码问题的结论来改进您的问题。问题最有可能出现在ShowFileInfo()中实现。您能显示分配
htmlFile
参数的代码吗?我会完全消除A2OLE/多字节编码的内容。
const char*file
在Windows上尤其没有意义;路径是UTF-16。我尝试将项目迁移到UNICODE,但没有任何更改。您好,我检查了A2OLE宏和t客户端的BSTR字符串已正确初始化。我还修改了服务器方法,如您的建议(BSTR*htmlfile)。客户端的方法调用和参数是正确的。但是,当服务器启动该方法时,参数仍然不正确。服务器返回的字符串指针也不正确。只有HRESULT返回值是正确的。我真的很困惑?我添加了类工厂(EDIT2)的实现to可以排除任何实现错误。我当前注意到客户端搜索接口ICallFactory,并返回E_INVALIDARG。是否应实现此接口?另一个问题:“HKCR\CLSID\\InProcServer32”“-标准条目必须指向COM服务器或代理/存根DLL?@Tobias:我严重怀疑代理/存根是否可调试-其中包含大量生成的代码。在您的情况下,您可以使用Automation marshaller—您的接口与Automation兼容,您可以通过在IDL中添加
oleautomation
标记并注册typelib来使用Automation代理/存根-
HRESULT CShellServerx86::ShowFileInfo(BSTR file, BSTR* htmlFile, BSTR pathBSTR)
{
    if( htmlFile == 0 ) {
       return E_POINTER;
    }
    // do useful stuff, generate the string for the htmlFile, then
    *htmlFile = SysAllocString( TheStringForHtmlFileParameter );
    return S_OK;
}
BSTR htmlFileBstr = ::SysAllocString(A2OLE(""));
//Call method of Server
hr = pShellServer->ShowFileInfo(filebstr, &htmlFileBstr, pathBstr);
BSTR htmlFileBstr = 0;
//Call method of Server
hr = pShellServer->ShowFileInfo(filebstr, &htmlFileBstr, pathBstr);