0
DCOMサーバーとクライアントを作成して、データを交換できるようにしたいとします。両面はMS Visual Studio 2008を使用してコンパイルされ、クライアントは純WinAPIを使用して接続され、プロキシ/スタブは別のdllです(この場合は何でも可能です)。問題は、文字列の配列を返すことができないことです(クライアントは空の文字列を受け取りますが、正しく埋められています)。DCOMの[out]パラメータとしてのSAFEARRAY(BSTR)が文字列を返さない
サーバー:COMインターフェースの IDL宣言は、この方法がありますメーカーによって生成されるヘッダと
[id(7)] HRESULT foo([in] int arg1, [out] SAFEARRAY(int)* arg2, [out] SAFEARRAY(BSTR)* arg3);
実装:
HRESULT STDMETHODCALLTYPE CoClass::foo(int arg1, SAFEARRAY** arg2, SAFEARRAY** arg3){
SAFEARRAYBOUND bounds;
bounds.cElements = arg1;
bounds.lBound = 0;
*arg2 = SafeArrayCreate(VT_INT, 1, &bounds);
*arg3 = SafeArrayCreate(VT_BSTR, 1, &bounds);
for(LONG i=0; i<arg1; ++i){
int int_value = 42;
BSTR string_value = SysAllocString(L"Hello");
//string_value is correct here
SafeArrayPutElement(*arg2, &i, &int_value);
SafeArrayPutElement(*arg3, &i, &string_value);
//string_value isn't destroyed here (explicitly, at least)
}
return ERROR_SUCCESS;
}
クライアント:含まスタジオ生成されたヘッダー。
virtual /* [id] */ HRESULT STDMETHODCALLTYPE foo(
/* [in] */ int arg1,
/* [out] */ SAFEARRAY * *arg2,
/* [out] */ SAFEARRAY * *arg3) = 0;
発信者コード(pInterface
が正しく初期化され、他の呼び出しが成功している):
SAFEARRAY *pInts = NULL, *pStrings = NULL;
HRESULT error = pInterface->foo(23, &pInts, &pStrings);
// in debugger:
// error is ERROR_SUCCESS, pInts filled properly,
// pStrings is an array of 23 NULLs
その他の詳細:
- IDLファイルでID 7を持つ他の方法はありません。
[out] BSTR *str
を使用すると、文字列が正しく返されます。pInterface
は、CoCreateInstanceEx
から呼び出されます。- システムに古いバージョンのサーバーはありません。
- コードはWindows XPで更新されずに実行されるため、Visual Studio 2008を使用することはバイパスが困難な制約です。
私は何が間違っているのか考えている人はいますか?
BSTRは既にポインタであり、パス&string_valueの代わりにstring_value –
@HansPassant ...これは働いた。ありがとうございました。あなたは答えを書いてほしいですか、それとも自分自身で行うべきですか? – Abstraction
私はあなたが今正しい答えを書く方法を知っていると確信しています。 –