7

一个很长的标题,但我希望它是具体的。标题确实是个问题。即使InvokeMember正在调用的方法有一个out参数并且正在为该参数分配一个值,我也无法获取该值。这是我最初使用的代码:

string parameter = "";
int result = Convert.ToInt32(typeof(Ability).InvokeMember(selectedMove, BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, new object[] { parameter }));

我改变了它,现在使它按预期工作,但我不知道为什么:

object[] args = new object[1];      //necessary to retrieve ref/out parameter
int result = Convert.ToInt32(typeof(Ability).InvokeMember(selectedMove, BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, args));
4

3 回答 3

9

我只是想帮助那些在非托管(COM)方面苦苦挣扎(我做过)并获得参考参数的人。因此,当针对 COM 方法使用 InvokeMember 时,您必须知道哪些参数是 ref 类型。这是通过使用 ParameterModifier-class 来实现的,例如:

object[] args = new object[3] { param1, param2, errorStr };
ParameterModifier pMod = new ParameterModifier(3);
pMod[2] = true;            
ParameterModifier[] mods = { pMod };

object tempObj = myCOMObject.GetType().InvokeMember("MyCOMMethod", BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Public, null, myCOMObject, args, mods, null, null);

在上面的代码中,第三个参数被设置为一个引用 (pMod[2] = true;)

于 2014-09-24T07:30:25.900 回答
5

您的第二个片段缺少一行相当重要的代码。它应该看起来像这样,假设out参数是字符串类型:

object[] args = new object[1];      //necessary to retrieve ref/out parameter
int result = Convert.ToInt32(typeof(Ability).InvokeMember(selectedMove, 
    BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, 
    null, null, args));
string outValue = (string)args[0];  // <===  here!

现在也应该很明显为什么您的第一个片段无法工作,您没有对传递的 object[] 数组的引用,因此您永远无法检索修改后的参数。

于 2012-03-26T23:20:31.773 回答
3

在您的第一个代码示例中,调用InvokeMember不会修改parameter变量的值,它只是替换参数数组中的第一项(现在指向不同的string实例)。由于您没有保留对该数组的引用,因此您无法检索输出参数的值。

换句话说:数组最初包含parameter变量的副本(即对空字符串的引用的副本)。调用后,parameter数组中的值引用了 2 个不同的字符串实例。

于 2012-03-26T23:00:01.530 回答