C ++ IDispatch使用输出参数调用

时间:2017-04-11 07:55:50

标签: com

我正在开发一个应用程序,它连接到COM对象并调用方法并从此对象获取属性等。 我可以联系并致电会员,这不是问题。我无法弄清楚,如何调用一个具有输出参数的方法,例如(伪代码):

int GetAppVersion(bsRetMsg [out, optional]). 

此函数返回int作为版本,并且还可以通过输出参数返回版本的字符串表示。

我尝试了什么:

(1)

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

        BSTR str = SysAllocString(L"longerfoostring");
        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;
...

(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 个答案:

答案 0 :(得分: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;

现在调用invoke并且不要忘记释放返回的BSTR。