2013-10-21 106 views
1

假设我有,我已经通过Activator.CreateInstance实例化一个COM对象:C#COM通过MethodInfo.Invoke进行互操作:int *参数?

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? 
+0

用OleView打开您的COM DLL,并向我们显示您的Method的确切签名,如IDL中所定义。我希望它看起来像'HRESULT方法([out] int * p)'我的答案适用。 – Noseratio

回答

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包装器。

+0

看来,我正在尝试使用的对象不是一个适当的COM对象(可能为什么我不能直接实例化它)我现在正在C++/CLI包装,虽然我是试图避免这一点! – dsharlet

0

尝试传球int阵列与一个单一的元素parametersmethod.Invoke

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