2016-06-30 7 views
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を使用することはバイパスが困難な制約です。

私は何が間違っているのか考えている人はいますか?

+1

BSTRは既にポインタであり、パス&string_valueの代わりにstring_value –

+0

@HansPassant ...これは働いた。ありがとうございました。あなたは答えを書いてほしいですか、それとも自分自身で行うべきですか? – Abstraction

+0

私はあなたが今正しい答えを書く方法を知っていると確信しています。 –

答えて

2

回答は、コメント欄にHans Passantで提供されました。

答えは:SAFEARRAYに要素を追加する構文は、intBSTRで異なる:読書の構文は同じであること

// SAFEARRAY **intArray, **stringArray; LONG i; 
int int_value = 42; 
BSTR string_value = SysAllocString(L"Hello"); 

SafeArrayPutElement(*intArray, &i, &int_value); 
//SafeArrayPutElement(*stringArray, &i, &string_value); //WRONG! 
SafeArrayPutElement(*stringArray, &i, string_value); //Right 

// SAFEARRAY *intArray, *stringArray; LONG i; 
int int_value; 
BSTR string_value; 

SafeArrayGetElement(intArray, &i, &int_value); 
SafeArrayGetElement(stringArray, &i, &string_value); 
関連する問題