【发布时间】:2014-04-25 22:43:04
【问题描述】:
我有一个正在使用的第 3 方 COM 对象。大部分都很好,但我一直坚持从对象中读取 GUID 属性。
自动生成的组件包装器/标题的相关部分如下所示:
// *********************************************************************//
// DispIntf: IFoo
// Flags: (4416) Dual OleAutomation Dispatchable
// GUID: {5DE5DAAF-5419-4B2B-9771-58EAEE780799}
// *********************************************************************//
template<class T>
class IFooDispT : public TAutoDriver<IFoo>
{
...
BSTR __fastcall get_FileName(void);
HRESULT __fastcall get_ProjectGUID(/*AUTO_PARAM_ERROR(System::TGUID* Value)*/ VARIANT* Value);
HRESULT __fastcall get_ProjectName(BSTR* Value/*[out,retval]*/);
__property BSTR FileName = {read = get_FileName};
__property BSTR ProjectName = {read = get_ProjectName};
注意ProjectGUID 属性是如何标记为AUTO_PARAM_ERROR 的,并且它没有出现在属性列表中。
我尝试通过get_ProjectGUID() 直接读取它,但它总是返回HRESULT = 0x80070057 (E_INVALID_ARGS)。
来自 OleView 的调度接口的 IDL 如下所示:-
[
uuid(5DE5DAAF-5419-4B2B-9771-58EAEE780799),
version(1.0),
helpstring("Dispatch interface for xpCOMFoo Object"),
dual
]
dispinterface IFoo {
properties:
methods:
<...snipped...>
[id(0x000000cf), propget]
BSTR FileName();
[id(0x000000d0), propget]
GUID ProjectGUID();
[id(0x000000d1), propget]
BSTR ProjectName();
};
我已经从 Delphi 测试了同一个对象(尽管没有使用上面显示的后期绑定),我很高兴 COM 对象本身没有错误。
【问题讨论】:
-
可以用OleView展示TLB的IDL的相关部分吗?
-
COM 对象本身有问题。 dispinterface 的方法需要可以使用 IDispatch::Invoke() 调用。这要求方法的参数和返回值可以存储在 VARIANT 中。您不能将 GUID 存储在 VARIANT 中。它实际上不是一个调度接口,它具有 [dual] 属性。只能提前调用方法。
标签: com c++builder