Shellextensionsで64ビットと32ビットの問題を回避するために、Visual Studio 2010でC++でOut-Of- (http://blog.mattmags.com/2007/06/30/accessing-32-bit-dlls-from-64-bit-code/)。Out-Of-Proc-COM-Server:BSTRが適切にマーシャリングされていない
私は、IDL-ファイルにここのようなインターフェイス(http://msdn.microsoft.com/en-us/library/ms686605%28v=VS.85%29.aspxを)説明:
import "unknwn.idl";
[
object,
uuid("xx"),
helpstring("IShellServerx86-Interface")
]
interface IShellServerx86 : IUnknown
{
HRESULT ShowFileInfo([in]BSTR file, [out]BSTR* htmlFile, [in]BSTR pathChar);
};
をこのファイルには、私がまた標準マーシャラーメソッドを使用するように登録し、プロキシ/スタブ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 filebstr = ::SysAllocString(A2OLE(file));
BSTR pathBstr = ::SysAllocString(A2OLE(pathChar));
BSTR htmlFileBstr = ::SysAllocString(A2OLE(""));
をBSTRは正しく生成されますが、COMメソッドが呼び出されると(彼はそれを見つけます!)、dllhost.exeにデバッグします。間違ったエンコーディングが選択された場合、パラメータは無効です。私はプロジェクト全体を "Unicode"に設定しようとしましたが、何も変わりません。
設定を忘れてしまったのですか、マーシャリングのために他のデータ型を試す必要がありますか?
ありがとうございました。
EDIT:
クライアントの実装は次のとおりです。
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_t * -arraysとしてストリング。しかし、例えばサーバーメソッドの文字列 "file"の内容は0x02546e80 "㤈榧"のようなものです。
エンコーディングは、マルチバイトエンコーディング(Visual Studio)に設定されているすべてのプロジェクト(クライアント/サーバー)用です。
EDIT2:
サーバはfollwedとして宣言されている:インタフェースの
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();保護
//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);
: ULONG m_uRefCount。 };
のGetClass-方法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;
}
BSTRには1つのエンコードutf16しかありません。 A2OLE()変換を間違えるようにする機会は十分に残されています。これは、デフォルトのコードページに非常に依存しています。エンコーディングの問題がどのように結論づけられたかを文書化して、質問を改善してください。 –
この問題は、ShowFileInfo()実装の可能性が最も高いです。 'htmlFile'パラメータを割り当てるコードを表示してください。 – sharptooth
私は、A2OLE/Multibyteのエンコーディングを完全に排除します。 'const char * file'は特にWindowsでは意味をなさない。パスはUTF-16です。 – MSalters