【发布时间】:2015-02-24 06:13:17
【问题描述】:
我有一个用 VB.net 编写的 COM 组件。此 COM 组件的接口是
Public Interface IEdge
Function FooFunc() As Integer
Function Exec(ByVal modelName As String, ByVal Params As Object()) As Object
Sub Foo()
Sub Fooint(ByVal a As Integer)
End Interface
我在 Native C++ 代码中使用这个 COM 组件的类型库
#import "..\Edge.tlb" named_guids raw_interfaces_only
Main 的 C++ 代码是
int _tmain(int argc, _TCHAR* argv[])
{
HRESULT hr = CoInitialize(NULL); //Initialize all COM Components
ICOMEdgePtr myEdge;
HRESULT hRes = myEdge.CreateInstance(CLSID_COMEdge);
if (hRes == S_OK)
{
VARIANT lResult ;
BSTR str;
myEdge->Foo();
myEdge->Fooint(1234);
long abc = 0;
myEdge->FooFunc(&abc);
SAFEARRAYBOUND aBound[2];
aBound[1].cElements = 2;
aBound[1].lLbound = 0;
SAFEARRAY* sf = SafeArrayCreate(VT_INT, 1, &aBound[1]);
long index1=0;
int val1=20;
SafeArrayPutElement(sf, &index1, &val1);
long index2=1;
int val2=30;
SafeArrayPutElement(sf, &index2, &val2);
myEdge->Exec(L"Add", sf, &lResult);
//Using lResult after this
}
CoUninitialize ();
return 0;
}
我可以致电FooFunc()、Foo()、Fooint()。
但是我无法调用Exec函数,它没有显示任何错误,没有报告崩溃。
为了测试,我在 VB.net 中使用了这个 COM 组件(使用 CreateObject(CLSID)),并且可以从那里调用 Exec。我需要从 Native C++ 调用它。
我怀疑SafeArray 和Object() 转换存在一些问题。接口定义错了吗?
我尝试了System.Array、<MarshalAs(UnmanagedType.SafeArray)>,但没有解决问题。我已经提出了一个MsgBox() 作为Exec 定义的第一条语句,这样我就可以知道Exec 是否被调用。
【问题讨论】:
-
此代码缺少所有必需的错误检查。它告诉你你做错了什么。 VTINT 的 SafeArray 仅匹配 VB.NET 中的 Integer()
-
@HansPassant Trying now for Integer()... 实际的 C++ 代码具有异常处理功能,但没有捕获任何与此相关的内容。
-
@HansPassant 使用 VT_VARIANT 而不是 VT_INT。一切正常,感谢您的帮助。