首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何获得派生接口而不具有返回它的属性/函数(OLE/COM)

如何获得派生接口而不具有返回它的属性/函数(OLE/COM)
EN

Stack Overflow用户
提问于 2016-11-28 04:28:33
回答 2查看 116关注 0票数 0

我正在使用C++客户端代码与VB应用程序进行接口。我在这方面完全是个新手(我只是个化学工程师),所以如果这个问题很愚蠢,请原谅。

因此,访问"BackDoor“接口需要使用VB中的以下代码,因为我遵循层次结构(如strm =BackDoor),因此可以获得所有其他接口。

但是您可以在下面的代码中看到,BackDoor接口等同于ProcessStream接口!!我不明白这一点,也不知道如何在C++中实现.你能帮忙吗?

VB中的代码:

代码语言:javascript
复制
Function GetMassExergy(strmName As String) As Double

GetMassExergy = EmptyValue_enum.HEmpty 'initialize to empty

Dim strm As ProcessStream

Dim bd As BackDoor

Dim corrNamesVar As TextFlexVariable

Dim corrNames() As String

Dim i As Integer

Dim exergMoniker As String

Dim exerg As RealVariable

Dim Bval As Double

strm = hyApp.ActiveDocument.Flowsheet.Streams.Item(strmName)

bd = strm

corrNamesVar = bd.BackDoorTextVariable("HysysCorrelation.300.[]:Name.0").Variable

corrNames = corrNamesVar.Values

For i = 0 To corrNames.Count - 1

If corrNames(i) = "Mass Exergy" Then

Exit For

End If

Next i

If i = corrNames.Count Then

'failed to find Mass Exergy Correlation

Exit Function

End If

exergMoniker = String.Format("HysysCorrelation.300.{0}:ExtraData.550.0", i)

exerg = bd.BackDoorVariable(exergMoniker).Variable

Bval = exerg.GetValue("kJ/kg")

GetMassExergy = Bval

End Function 

C++中的代码:

代码语言:javascript
复制
 void ConnectToHYSYS::GetBackDoor() {
//HyStream is already acquired using Hierarchy 
IDispatch* hyStream;
// Try to Query BackDoor from hyCase interface
    HRESULT hr = hyStream->QueryInterface(__uuidof(hyBackDoor), (void**)&hyBackDoorDisp);

//Last hr returns S_OK
    if (SUCCEEDED(hr))
    {
        cout << "Got the BackDoor safely" << endl;
        //Get BackDoor Text Variable, 

            VARIANT result;
            VariantInit(&result);
// Try to Get a property from BackDoor interface (to make sure that it returned //an actual interface)
            hr = COMMethod(DISPATCH_PROPERTYGET, &result, hyBackDoorDisp, L"BackDoorTextVariable", 1, "HysysCorrelation.300.[]:Name.0");
            CheckForHr(hr);
            BackDoorTextVariable = result.pdispVal;
            if (SUCCEEDED(hr))
            {
                cout << "Got the BackDoor Text Variable safely" << endl;

            }

            if (FAILED(hr)) {
                cout << "Couldnt get the BackDoor Text Variable" << endl;

            }
    }

        if (FAILED(hr)) {
            cout << "Couldnt get the BackDoor" << endl;
        }

}

下面是用于访问接口内部属性的COMMethod (它与所有其他接口正常工作)

代码语言:javascript
复制
    HRESULT ConnectToHYSYS::COMMethod(int nType, VARIANT * pvResult, IDispatch * pDisp, LPOLESTR ptName, int cArgs...)
{
    if (!pDisp) return E_FAIL;

    va_list marker;
    va_start(marker, cArgs);

    DISPPARAMS dp = { NULL, NULL, 0, 0 };
    DISPID dispidNamed = DISPID_PROPERTYPUT;
    DISPID dispID;
    char szName[200];


    // Convert down to ANSI
    WideCharToMultiByte(CP_ACP, 0, ptName, -1, szName, 256, NULL, NULL);

    // Get DISPID for name passed...
    HRESULT hr = pDisp->GetIDsOfNames(IID_NULL, &ptName, 1, LOCALE_USER_DEFAULT, &dispID);
    if (FAILED(hr)) {
        return hr;
    }
    // Allocate memory for arguments...
    VARIANT * pArgs = new VARIANT[cArgs + 1];
    // Extract arguments...
    for (int i = 0; i < cArgs; i++) {
        pArgs[i] = va_arg(marker, VARIANT);
    }

    // Build DISPPARAMS
    dp.cArgs = cArgs;
    dp.rgvarg = pArgs;

    // Handle special-case for property-puts!
    if (nType & DISPATCH_PROPERTYPUT) {
        dp.cNamedArgs = 1;
        dp.rgdispidNamedArgs = &dispidNamed;
    }

    // Make the call!
    hr = pDisp->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT, nType, &dp, pvResult, NULL, NULL);
    if (FAILED(hr)) {
        return hr;
    }

    // End variable-argument section...
    va_end(marker);
    delete[] pArgs;
    return hr;
}

我调用的行是唯一返回错误"0x80020008坏变量类型“的行.我的意思是在COMMethod中写的"hr =pDisp->Invoke“(dispID,IID_NULL,LOCALE_SYSTEM_DEFAULT,nType,&dp,pvResult,NULL,NULL);

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-11-29 03:18:06

Igor先生和Acelent先生的回答都是成功的(对不起,我不知道如何接受Igor先生的答复,所以我将把它复制到这里,并把它作为其他面临同样问题的人的答案。

pArgsi =va_arg(标记,变体);这显示了未定义的行为,因为传递给COMMethod的实际参数实际上不是一个变量:COMMethod(.,1,“HysysCorrelated.300.”[]:name.0“);- Igor

谢谢大家..。

票数 0
EN

Stack Overflow用户

发布于 2016-11-28 23:11:18

您拥有的VB代码使用的是早期绑定,而C++代码使用的是后期绑定。

将C++代码转换为类似于VB代码的代码,例如:

代码语言:javascript
复制
void ConnectToHYSYS::GetBackDoor() {
    IDispatch* hyStream = ...;

    // Use an actual hyBackDoor
    hyBackDoor* hyBackDoorDisp;    
    HRESULT hr = hyStream->QueryInterface(IID_PPV_ARGS(&hyBackDoorDisp));

    if (SUCCEEDED(hr)) {
        cout << "Got the BackDoor safely" << endl;

        // From the VB code, it seems BackDoorTextVariable is a TextFlexVariable
        hr = hyBackDoorDisp->get_BackDoorTextVariable(&BackDoorTextVariable);

        CheckForHr(hr);
        if (SUCCEEDED(hr)) {
            cout << "Got the BackDoor Text Variable safely" << endl;
        }

        if (FAILED(hr)) {
            cout << "Couldnt get the BackDoor Text Variable" << endl;
        }
    }

    if (FAILED(hr)) {
        cout << "Couldnt get the BackDoor" << endl;
    }
}

您获得的调度对象不能工作的原因是,通常只有第一个接口由标准调度程序处理。即使是处理多个接口的自定义或手动调度程序,通常也不会分派隐藏(或其他用途)接口。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40837201

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档