2017-04-11 1 views
0

COM 개체에 연결하고 메서드를 호출하고이 개체 등에서 속성을 가져 오는 응용 프로그램에서 작업하고 있습니다. 구성원을 연결하고 호출 할 수는 있지만 그다지 문제는 아닙니다. C++ IDispatch 출력 매개 변수를 사용하여 호출

int GetAppVersion(bsRetMsg [out, optional]). 

이 기능

이 버전으로 INT를 반환하며 통해 버전의 문자열 표시를 리턴 할 수 I 그러나 출력 매개 변수를 가지고있어서, 예를 들어 (의사 코드)를 호출하는 방법을 알아낼 수 없다 출력 매개 변수.

나는 시도했다 :

(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의 실제 선언문을 요청하십시오. 전화를하는 동안 [in, out, optional]을 사용하여 올바르게 수행하도록 요청하십시오. 가장 좋은 추측은 NULL로 초기화되는 BSTR 변수 (BSTR * 아님)를 가리 키도록 pbstrVal (bstrVal 아님)을 설정해야하는 VT_BSTR | VT_BYREF입니다. –

+0

답변 해 주셔서 감사합니다. 정확한 정보와 기능을 DLL 개발자에게 묻습니다. HRESULT GetAppVersion ([out, optional] VARIANT * bsRetMsg, [out, retval] VARIANT * pVer); 그래서 사용했습니다 VARIANT * retVar = new VARIANT; 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을 해제하는 것을 잊지 마세요.

관련 문제