【发布时间】:2018-10-17 04:21:33
【问题描述】:
我有一个旧版 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,这意味着我有一个用户控件,我将这个 C# 用户控件的 progid 提供给遗留组件,它创建 C# 用户控件的对象并尝试调用 C# 用户控件的 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#?
注意:使用 InvokeHelper 调用方法的组件代码对于 C++ 和 C# 用户控件应该相同
【问题讨论】:
-
您的 GetValue 函数是否定义在接口中?请显示完整的代码。
-
@SimonMourier 我已经用接口定义更新了问题
-
您可以尝试在界面中为GetValue添加一个[PreserveSig]属性。
-
@SimonMourier 设置 [PreserveSig] 没有帮助:(
-
我们需要一个完整的复制代码才能提供帮助。
标签: c# c++ com variant dispatch