C#COM interop通过MethodInfo.Invoke:int *参数?

时间:2013-10-21 03:43:22

标签: c# com interop

假设我有一个我通过Activator.CreateInstance实例化的COM对象:

object obj = Activator.CreateInstance(myGuid);

现在,我知道这个对象有一个接受int *作为参数的函数:

virtual void Method(int * outParameter) = 0;

此方法只是将一个整数写入outParameter。在C ++中,我会这样做:

int parameter = 0;
obj->Method(&parameter);
// parameter now contains the result.

如何通过MethodInfo.Invoke在C#中执行等效操作?

MethodInfo method = obj.GetType().GetMethod("Method", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
method.Invoke(obj, ???); // What do I put here?

2 个答案:

答案 0 :(得分:1)

你不能,那不是COM兼容的功能签名。它必须必须返回一个HRESULT才能兼容,你必须在方法上用[PreserveSig]声明接口,这样CLR就知道不检查返回值并抛出异常。它还缺少必需的__stdcall属性(又名STDMETHOD),这是另一个COM要求。

你唯一的希望是你的C ++声明错了。最快的检查方法是使用动态关键字:

dynamic obj = Activator.CreateInstance(myGuid);
int parameter;
obj.Method(out parameter);

或者,因为它实际上看起来很像属性getter:

int parameter = obj.Method();

但期望它会随机抛出异常和/或使堆栈失衡。需要进行彻底的测试,以确保随机返回值不会触发异常。

然而,这是很多猜测,最好不要这样做,特别是如果你确定签名。改为编写C ++ / CLI包装器。

答案 1 :(得分:0)

尝试在int parameters中使用单个元素传递method.Invoke数组:

var byrefArg = new int[1];
method.Invoke(obj, .... , new Object[] { byrefArg }, ...);
var outParameter = byrefArg[0];