A long title, but I wanted it to be specific. The title is really the question. Even though the method that InvokeMember
is calling has an out
parameter and is assigning a value to to that parameter I can't grab that value. Here is the code I was initially using:
string parameter = "";
int result = Convert.ToInt32(typeof(Ability).InvokeMember(selectedMove, BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, new object[] { parameter }));
I changed it this, which now makes it work as intended but I don't know why:
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));
I just wanted to help someone who is struggling(I did) with unmanaged(COM) and getting ref-parameter back. So, when using InvokeMember against COM-method, you have to tell which arguments are ref-type. This is achieved by using ParameterModifier-class, For example:
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);
In the code above, the 3rd argument is set to be a reference (pMod[2] = true;)
Your second snippet is missing a rather essential line of code. It should look like this, assuming the out argument is of type string:
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!
It should now also be obvious why your 1st snippet cannot work, you don't have a reference to the object[] array that you pass so you can never retrieve the modified argument.
In your first code example, the call to InvokeMember
doesn't modify the value of the parameter
variable, it just replaces the first item in the parameter array (which now points to a different string
instance). Since you didn't keep a reference to this array, you can't retrieve the value of the output parameter.
In other words: the array initially contains a copy of the parameter
variable (i.e. a copy of the reference to an empty string). After the call, parameter
and the value in the array refer to 2 different string instances.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With