我有一个遗留的c ++组件,它使用了性质相似的ATL控件,程序ID输入到该组件。它使用progid创建ATL对象,并使用dispatchid通过InvokeHelper从ATL控件调用方法,如下所示,
DISPID methodDispID; // dispatchid
long lValue = 0; // first argument long
short nIdx = 1 // second argument short
VARIANT varValue; // third argument variant
long returnCode = 0; // return code long
static BYTE parms[] = VTS_I4 VTS_I2 VTS_PVARIANT;
InvokeHelper(methodDispID, DISPATCH_METHOD, VT_ERROR, (void*)&returnCode, parms, &varValue, lValue, nIdx);
在C ++ ActiveX方法中,如下所示,
[id(1), helpstring("method GetValue")] long GetValue(long lValue, short nIdx,VARIANT *varValue);
现在,我尝试在C#中引入Active X,这意味着我有一个Usercontrol,我将此C#usercontrol的progid提供给了遗留组件,它创建了C#usercontrol的对象,并尝试调用C#Usercontrol的GeValue方法,在下面定义,
C#
interface IMyInterface
{
[DispId(1)] Int32 GetValue(System.Int32 lOrder, System.Int16
nIdx,object varval);
}
class MyClass : IMyInterface
{
System.Int32 GetValue(System.Int32 lValue, System.Int16 nIdx,
ref object vCBValue)
{
}
}
该调用即将到达C#用户控件的GetValue方法,但会引发异常
System.Runtime.InteropServices.COMException 在 System.RuntimeType.ForwardCallToInvokeMember(System.String, System.Reflection.BindingFlags,System.Object,Int32 [], System.Runtime.Remoting.Proxies.MessageData ByRef)
我尝试如下更改C#方法定义,但无济于事,
System.Int32 GetValue(System.Int32 lValue, System.Int16 nIdx,
[MarshalAs(UnmanagedType.Struct)] ref object varValue);
System.Int32 GetValue(System.Int32 lValue, System.Int16 nIdx,
ref IntPtr varValue);
如何通过InvokeHelper将variant *传递给C#?
注意:对于C ++和C#用户控件,使用InvokeHelper调用该方法的组件代码应该相同
答案 0 :(得分:0)
如果您想重现c ++ COM代码:
[id(1), helpstring("method GetValue")]
long GetValue(long lValue, short nIdx,VARIANT *varValue);
...改为c#,然后代替
System.Int32 GetValue(System.Int32 lValue, System.Int16 nIdx, ref object vCBValue);
...应该是:
object GetValue(System.Int32 lValue, System.Int16 nIdx);
那是因为所有c ++ COM方法都返回一个HRESULT(在您的情况下为long),其他任何返回值都是通过out
参数来实现的。
在.NET中,无需定义HRESULT,我们可以显式返回值,而不必使用out