2016-06-30 39 views
0

我想編寫一個DCOM服務器和一個客戶端,以便他們可以交換一些數據。雙方都使用MS Visual Studio 2008進行編譯,客戶端使用純WinAPI進行連接,代理/存根是一個單獨的dll(以防這種情況發生)。問題是,我無法返回一個字符串數組(它被正確填充,但客戶端接收到一個空字符串數組)。SAFEARRAY(BSTR)在DCOM中[out]參數無法返回字符串

服務器:由Studio所產生

[id(7)] HRESULT foo([in] int arg1, [out] SAFEARRAY(int)* arg2, [out] SAFEARRAY(BSTR)* arg3); 

實現,與標頭::COM接口的 IDL聲明有此方法

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工作,字符串被正確返回;
  • pInterfaceCoCreateInstanceEx收到呼叫;
  • 系統上沒有舊版本的服務器;
  • 該代碼將在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); 
相關問題