2017-04-11 74 views
0

我上的應用程序,它連接到一個COM對象,並調用方法,並得到從這個對象等 屬性我可以連接並調用成員的工作,這不是問題。我不能然而弄清楚,如何調用的方法,其具有一個輸出參數,例如(僞碼):C++ IDispatch接口調用與輸出參數

int GetAppVersion(bsRetMsg [out, optional]). 

此函數返回INT作爲版本,並且還可以通過返回的版本的字符串表示輸出參數。

我已經試過:

(1)

(2)

 VARIANT result; 
     DISPPARAMS params = {NULL, NULL, 0, 0}; 
     VARIANTARG args[1]; 

     BSTR str = SysAllocString(L""); // change: empty string 
     VariantInit(&args[0]); 
     args[0].vt = VT_BSTR | VT_BYREF; 
     args[0].bstrVal = str; 
     params.rgvarg = args; 
     params.cArgs = 1; 

     res = dispatch->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &params, &result, NULL, 
           NULL); 

     if (SUCCEEDED(res)) { // here it failed: Not enough storage is available to complete this operation. 
      std::cout << result.intVal << std::endl; 
... 

(3)

... 
BSTR str = SysAllocString(L"longerfoostring"); 
VariantInit(&args[0]); 
args[0].vt = VT_BSTR; // change: no BYREF 
args[0].bstrVal = str; 
params.rgvarg = args; 
params.cArgs = 1; 
... invoke is the same... 
res = dispatch->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &params, &result, NULL, 
           NULL); 
if (SUCCEEDED(res)) { 
    std::cout << result.intVal << std::endl; // this number is correct - version in int 
    printf("'%S'", params.rgvarg[0].bstrVal); // prints 'longerfoostring' instead of version, ie. '2.0.5...' 

(4)

BSTR *str; 
VariantInit(&args[0]); 
args[0].vt = VT_BSTR | VT_PTR; // change: different VT 
args[0].pbstrVal = str; //change: different type 
params.rgvarg = args; 
params.cArgs = 1; 
... invoke failes with Bad variable type. 

所以問題是: 如何將一個字符串(或任何類型)作爲輸入/輸出參數傳遞給一個COM方法,並正確地從該參數獲取輸出?

+1

這聲明使得很少的感覺,確實張貼了真正的代碼,而不是「僞」的代碼。向作者詢問他的IDL中的實際聲明。在你打電話的時候,讓他用[進出,可選]做對。最好的猜測是VT_BSTR | VT_BYREF,需要設置pbstrVal(不bstrVal)指向一個BSTR變量(不BSTR *)被初始化爲NULL。 –

+0

感謝您的回答,我問的dll開發精確的信息和功能是: HRESULT GetAppVersion([出,可選] VARIANT * bsRetMsg,[出,retval的] VARIANT * PVER); 所以我用 VARIANT * retVar =新變體; VariantInit(retVar); v.pvarVal = retVar; v.vt = VT_VARIANT | VT_BYREF; 和它的工作真的很好 謝謝! – kn0t3k

回答

0

既然你想找回數據,你必須提供一個BSTR

BSTR str; 
VariantInit(&args[0]); 
args[0].vt = VT_BSTR | VT_BYREF; // it's a BSTR and it's by ref 
args[0].pbstrVal = &str; // give address of variable 
params.rgvarg = args; 
params.cArgs = 1; 

的地址現在稱之爲調用,不要忘記釋放返回BSTR。