我使用Visual Studio 2010用C ++开发了Pro-Proc-COM-Server,以避免Shellextensions(http://blog.mattmags.com/2007/06/30/accessing-32-bit-dlls-from-64-bit-code/)中的64位和32位问题。

我在IDL文件中描述了像这里的接口(http://msdn.microsoft.com/en-us/library/ms686605%28v=VS.85%29.aspx):
ojit_pre

该文件为我生成了一个Proxy / Stub-DLL,我也注册了该文件以使用标准Marshaller方法。
如果我现在打电话

import "unknwn.idl";
[
 object,
 uuid("xx"),
 helpstring("IShellServerx86-Interface")
]
interface IShellServerx86 : IUnknown
{
   HRESULT ShowFileInfo([in]BSTR file, [out]BSTR* htmlFile, [in]BSTR pathChar);
};


服务器已创建,我可以调用该方法

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”,但没有任何变化。

我忘记了任何设置还是应该尝试其他数据类型进行编组?

预先感谢您的帮助。

编辑:

客户端的实现是:

BSTR filebstr = ::SysAllocString(A2OLE(file));
BSTR pathBstr = ::SysAllocString(A2OLE(pathChar));
BSTR htmlFileBstr = ::SysAllocString(A2OLE(""));


服务器方法声明如下:

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;
}


在服务器和客户端方法中,调试器将BSTR字符串识别为wchar_t * -arrays。但是服务器方法中字符串“ file”的内容例如是:0x02546e80“㤈榧”。

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

编辑2:

服务器声明为以下:

HRESULT CShellServerx86::ShowFileInfo(BSTR file, BSTR* htmlFile, BSTR pathBSTR)
{...
 //TODO
}


接口的实现:

class IShellServerx86 : public IUnknown {
  public:

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

};


...和阶级工厂
    CShellServerx86ClassFactory类:public IClassFactory {
    上市:
      CShellServerx86ClassFactory();
      〜CShellServerx86ClassFactory();

//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;
};


受保护的:
     ULONG m_uRefCount;
   };

DLL中的GetClass-Method:

 //inherited methods from IUnknown
 ULONG STDMETHODCALLTYPE AddRef(void);
 ULONG STDMETHODCALLTYPE Release(void);
 HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppv);

 //inherited methods from IClassFactory
 HRESULT STDMETHODCALLTYPE CreateInstance(IUnknown *pUnkOuter,
                                          REFIID riid, void** ppv);
 HRESULT STDMETHODCALLTYPE LockServer(BOOL fLock);


}

最佳答案

首先,您必须检查案例中产生的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);


同样,您也会泄漏所有BSTR,因为完成后您不会调用SysFreeString()。在您拥有的每个SysFreeString()上调用BSTR,或者最好使用包装类,例如ATL::CComBSTR_bstr_t

关于c++ - 进程外COM服务器:BSTR未正确编码,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6983471/

10-12 03:35