【发布时间】:2016-12-03 06:49:02
【问题描述】:
在我的 C++ 程序中,我使用了一个在 VB6 COM DLL 中实现的 COM 类。我们称这个类为CETicketRA。此类具有 AppliedPromotion 类型的属性 IPositionPromotion。 IPositionPromotion 是同一个 VB6 COM DLL 定义的接口。它具有我尝试从 C++ 访问的各种属性和方法。
给定以下代码:
IDispatch* pETicketRA = NULL;
DISPPARAMS dispParams = {0};
VARIANT result;
VariantInit(&result);
// Left out: some code to set pETicketRA ...
OLECHAR* strAppliedPromotion = L"AppliedPromotion";
DISPID dispIDAppliedPromotion = -1;
HRESULT hr = pETicketRA->GetIDsOfNames(IID_NULL, &strAppliedPromotion, 1, LOCALE_SYSTEM_DEFAULT, &dispIDAppliedPromotion);
hr = pETicketRA->Invoke(dispIDAppliedPromotion, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, &dispParams, &result, NULL, NULL);
IDispatch* pPromo = NULL;
hr = result.pdispVal->QueryInterface(IID_IDispatch, reinterpret_cast<LPVOID*>(&pPromo));
VariantClear(&result);
现在我尝试读取IPositionPromotion 的属性Foobar:
OLECHAR* strFoobar = L"Foobar";
DISPID dispIDFoobar = -1;
hr = pPromo->GetIDsOfNames(IID_NULL, &strFoobar, 1, LOCALE_SYSTEM_DEFAULT, &dispIDFoobar);
很遗憾,最后一次调用失败并显示DISP_E_UNKNOWNNAME。
有没有人成功地从 C++(或 C#)调用 VB6 接口成员?
【问题讨论】:
-
在 C# 中,您可以使用
dynamic进行 VB6 样式的操作。对于 C++,stackoverflow.com/q/11670175/11683 可能会有所帮助。 -
不确定 COM 规定是否更严格,但通常 C++ 在尝试在运行时访问对象时会破坏函数名称,从而导致动态错误。 如果是这种情况,请务必按要求
extern "C"。 -
@GSerg:我已经尝试过动态,它不起作用。但是我发现:在VB6 COM DLL中,在实现
IPositionPromotion的类中,实现IPositionPromotion接口的方法通常被声明为Private。他们被命名为IPositionPromotion_Foobar。如果我将它们从Private更改为Public,我可以在pPromo对象上调用IPositionPromotion_Foobar。但这是一个相当丑陋的“解决方案”。 -
@TimoKunze 它们应该是私有的,这是 VB6 实现接口和事件处理程序的约定。