【问题标题】:Access sub object in COM interface访问 COM 接口中的子对象
【发布时间】:2014-01-06 20:20:59
【问题描述】:

我想访问 COM 对象的子对象。在我的示例中,我使用 CANoe COM 服务器。

在我的程序中,我为 CANoe 应用程序创建了一个 CAN 接口。到目前为止,这是我的代码摘录,它完全符合我的要求:

HRESULT result;

//prepare for COM handling...
result = CoInitialize(NULL);

//get CLSID of CANoe...
result = CLSIDFromProgID(L"CANoe.Application", &clsid);


if(SUCCEEDED(result))
{
    //connect to COM interface of CANoe...
    result = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER, IID_IApplication, (void**) &pIApp);

    if(SUCCEEDED(result))

    {
        qDebug() << "COM connection established";
    }
    else
    {
        qDebug() << "COM connection error";
    }
}
else
{
    qDebug() << "Error: CLSID";
}

现在我想访问 COM 服务器的子对象。例如测量对象。我用pIApp-&gt;get_UI()的方法试了一下

IDispatch* pIDis;
IMeasurement* pIMeasurement;

result = pIApp->get_UI(&pIDis);

pIMeasurement = (IMeasurement*) pIDis;

指向COM对象的指针需要是IMeasurement类型的指针,所以我可以使用头文件中定义的所有方法。但是get_UI 方法只支持IDispatch 类型的指针。我试图将指针从 IDispatch 类型转换为 IMeasurement。但是程序在运行时崩溃。

我也尝试直接为子对象创建一个新接口:

    result = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER, IID_IMeasurement, (void**) &pIMeasurement);

但是在这个变量结果中的尝试中保存了一个错误,我无法访问子对象Measurement的方法。

我的错误在哪里?如何访问子对象?

感谢您的所有回答和提示!

【问题讨论】:

  • 我错过了什么,或者这不是QueryInterface 的全部意义吗?如果您确实查询了它并返回了 NULL(类似于您确实应该在此处发布的 result 中的错误),那么很可能该对象没有实现它您忘记构建适当的编组代理/存根,并分别在客户端和服务器机器上注册。
  • 转换 COM 接口指针从不正确,您必须使用 QueryInterface() 来获取指针。一个名为“UI”的属性似乎不太可能提供测量值,您需要知道对象模型才能做到这一点。联系供应商寻求支持。
  • 即使您只能获得 IDispatch,Visual Studio 也可以通过 #import 使使用基于 IDispatch 的界面变得更加容易。
  • 您好,感谢您的cmets。 QueryInterface 正是我搜索的关键字。

标签: c++ pointers interface com


【解决方案1】:

感谢 @WhozCraig、@Hans Passant 和 @Eric Brown 在 cmets 中的提示。

我能够使用以下代码解决我的问题:

 IDispatch* pIDispatch;

 //get pointer pIDispatch to Measurement object of CANoe...
 result = pIApp->get_Measurement(&pIDispatch);

 if(SUCCEEDED(result))
 {
    //pointer pIDispatch to pIMeasurement...
    result = pIDispatch->QueryInterface(IID_IMeasurement, (void**) &pIMeasurement);

    if(SUCCEEDED(result))
    {
       pIDispatch->Release();

       //work with connection here...

       pIMeasurement->Release();

    }

 }

【讨论】:

  • @sharptooth:嗯,我认为没有理由不使用智能指针。我将在未来的版本中使用它们。谢谢!一个问题只是为了更好地理解:智能指针有一个方便,我不需要手动删除它们,不是吗?但是它们并没有替代 COM 对象的方法 Release 的需要?
  • 特殊的智能指针,如CComPtr_com_ptr_tRelease() 对象,这将使您的代码干净三倍,并且异常安全。
猜你喜欢
  • 2012-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-12
  • 2011-06-27
  • 1970-01-01
  • 2015-10-13
  • 2013-08-21
相关资源
最近更新 更多