【问题标题】:COM Interop - Member not foundCOM 互操作 - 未找到成员
【发布时间】:2012-04-30 03:45:01
【问题描述】:

我正在尝试为第 3 方产品编写插件。这采用本机 C++ DLL 的形式,它从提供的类型库实现指定的接口。我的插件加载成功,接口描述的方法在预期点被调用,我可以从我的插件中写出一个日志文件并查询一个网络服务,到目前为止一切顺利。

但是,对于我的插件查询主程序,Initialize() 方法传递了一个IDispatch 接口。我正在尝试将此接口与如下代码一起使用:

Initialize(LPDISPATCH pDispArchivingControl) {
  LPOLESTR ptName = L"currentVaultId";
  HRESULT hr= pDispArchivingControl->GetIDsOfNames(IID_NULL, &ptName, 1, 
                         LOCALE_USER_DEFAULT, &dispID);
  // add parameters, etc
  hr = pDispArchivingControl->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT, 
                   DISPATCH_METHOD, &dp, pvResult, NULL, NULL);
  // hr = 0x80020003 Member not found.
}

第一部分GetIDsOfNames() 做了我认为应该做的事情,即将程序文档中的方法名称放入ptName 给我在dispID 中的不同值- 15、27 等等。

第二部分 Invoke() 始终返回 HRESULT 0x80020003(未找到成员)。

我在这里找到了一些解决方案:HOWTO: Troubleshoot "Member Not Found" 0x80020003 Error。对于解决方案 1,我尝试将 DISPATCH_METHOD 和 DISPATCH_PROPERTYGET 作为第四个参数。我是否正确假设 2 和 3 不能适用于我,因为我在 dispID 中取回了值?我也不确定如何更改这些。

我现在有点想不通,Google 也没有进一步帮助我 - 谁能建议下一步该做什么?


更新:这是 oleview 中的一种方法。我在树形视图中找不到它,但可以使用 File > View TypeLib 打开它...

【问题讨论】:

  • 听起来不太像一种方法。我们看不到dp,它实际上是一个索引属性?为什么在拥有类型库时使用后期绑定?用Oleview.exe看一下
  • @HansPassant 我正在使用后期绑定,因为我不知道自己在做什么 :) 我对 C++ 和 COM 还是很陌生。我也尝试过使用类型库的#import,但无法弄清楚如何将传递的接口连接到它 - 我尝试创建一个实例并将接口分配给它,它编译但在运行时给出“无效指针”。 #import 是否更适合这种情况?还是别的什么?
  • 如果幸运的话,导入应该创建一个IArchivingControl 接口,甚至可能创建一个IArchivingControlPtr ATL 智能指针类。如果您有智能指针,那么只需尝试将您的 IDispatch 分配给它,看看您是否获得了一个非空对象,然后您可以调用它。如果您没有智能指针,请尝试使用 IID_IArchivingControl 在 IDispatch 上调用 QueryInterface,它应该会为您创建一个 IArchivingControl 接口。完成后不要忘记Release他们俩。
  • 我们是如何从“TortoisCount”到“currentVaultId”的?它们是两个非常不同的源代码控制程序。 Tortoise 是免费软件 SVN 的包装器。我听说过 Vault,这是一个商业 SCCS。您是否尝试使用后期绑定来尝试忽略程序之间的根本差异?那是一条失败的鲸鱼。
  • @HansPassant 很抱歉造成混淆 - 代码示例只是显示我在做什么的几个示例行。截图是真正的类型库。我使用的是带有GetIDsOfNames() 的真实函数名称,我使用的是产品随附的文档

标签: c++ com


【解决方案1】:

Hans Passant 和 Rup 在 cmets 中给出的这个问题的正确答案不是使用后期绑定,而是使用类型库#import。

我把这个放在stdafx.h:

#import "ArchivingControl.tlb" raw_interfaces_only, raw_native_types, named_guids, auto_search

这在我的 .cpp 文件中:

ArchivingControl::IArchivingControlPtr JTArchivingControlPtr;
STDMETHODIMP CMyClass::Initialize(LPDISPATCH pDispArchivingControl)
{
   JTArchivingControlPtr = pDispArchivingControl;
   return S_OK;
}
STDMETHODIMP CMyClass::OtherFunction()
{
   BSTR pVaultId;
   JTArchivingControlPtr->get_currentVaultId(&pVaultId);
   return S_OK;
}

现在一切正常,而且我现在的代码少了很多 - 谢谢!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-16
    • 2011-02-21
    • 1970-01-01
    • 1970-01-01
    • 2011-02-25
    • 2010-12-14
    相关资源
    最近更新 更多