【发布时间】: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接口,甚至可能创建一个IArchivingControlPtrATL 智能指针类。如果您有智能指针,那么只需尝试将您的 IDispatch 分配给它,看看您是否获得了一个非空对象,然后您可以调用它。如果您没有智能指针,请尝试使用 IID_IArchivingControl 在 IDispatch 上调用QueryInterface,它应该会为您创建一个 IArchivingControl 接口。完成后不要忘记Release他们俩。 -
我们是如何从“TortoisCount”到“currentVaultId”的?它们是两个非常不同的源代码控制程序。 Tortoise 是免费软件 SVN 的包装器。我听说过 Vault,这是一个商业 SCCS。您是否尝试使用后期绑定来尝试忽略程序之间的根本差异?那是一条失败的鲸鱼。
-
@HansPassant 很抱歉造成混淆 - 代码示例只是显示我在做什么的几个示例行。截图是真正的类型库。我使用的是带有
GetIDsOfNames()的真实函数名称,我使用的是产品随附的文档