我有一个用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组件的Type Library#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
被调用。
答案 0 :(得分:1)
根据Hans Passant
给出的建议,我可以使用SAFEARRAY。
我在C ++中使用基于Dotnet的COM组件。最后,我更改了C ++代码以保持COM安全。
我已将VARIANT
替换为CComVariant
,将BSTR
替换为CComBSTR
,将SAFEARRAY
替换为CComSafeArray
。
现在Main的代码如下:
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)
{
CComVariant lResult ;
CComSafeArray<VARIANT> arr(2,0);
arr[0] = 20;
arr[1] = 30;
CComBSTR methodName;
methodName = L"Add";
myEdge->Exec(methodName, arr, &lResult);
wprintf(L"The result is %d\n", lResult.intVal);
//Using lResult after this
}
CoUninitialize ();
return 0;
}