Using out parameter in Dll method calls from C# appl. to C# dll

G

Gunnar Frenzel

Hello,
I have an application and dll both written in C#. The application uses methods and properties in the dll which works
fine so far, but I wasn't able use out parameters in methods call. I use the following structure to call the methods:

Assembly asmblyDll = Assembly.LoadFrom("theDll.dll");
Type tDll = asmblyDll.GetType("theDll.theDll");
object objDll = asmblyDll.CreateInstance("theDll.theDll");

string strToGet1 = string.Empty;
string strToGet2 = string.Empty;

ParameterModifier[] mods = new ParameterModifier[2] { new ParameterModifier(1), new ParameterModifier(1) };
mods[0][0] = true;
mods[1][0] = true;

object[] args = new object[2];
args[0] = strToGet1;
args[1] = strToGet2;

bool bRet = (bool)tDll.InvokeMember("theMethod", BindingFlags.InvokeMethod, null, objDll, args, mods, null, null);


theMethod is:
public bool theMethod(out string str1, out string str2)
{
str1 = "bla";
str2 = "blubb";
}



The ParameterModifier stuff was posted somewhere to use the parameters as out/ref parameters. But it didn't worked out.
Using ref in "theMethod" instead of out didn't work, too. The return value is correct and when the strToGet strings are
set to some strings then these are present in "theMethod" but changes to str1 and str2 didn't affect strToGet1 and
strToGet2.

Gunnar
 
C

Chris Jobson

Gunnar Frenzel said:
Hello,
I have an application and dll both written in C#. The application uses
methods and properties in the dll which works fine so far, but I wasn't
able use out parameters in methods call. I use the following structure to
call the methods:

Assembly asmblyDll = Assembly.LoadFrom("theDll.dll");
Type tDll = asmblyDll.GetType("theDll.theDll");
object objDll = asmblyDll.CreateInstance("theDll.theDll");

string strToGet1 = string.Empty;
string strToGet2 = string.Empty;

ParameterModifier[] mods = new ParameterModifier[2] { new
ParameterModifier(1), new ParameterModifier(1) };
mods[0][0] = true;
mods[1][0] = true;

object[] args = new object[2];
args[0] = strToGet1;
args[1] = strToGet2;

bool bRet = (bool)tDll.InvokeMember("theMethod",
BindingFlags.InvokeMethod, null, objDll, args, mods, null, null);


theMethod is:
public bool theMethod(out string str1, out string str2)
{
str1 = "bla";
str2 = "blubb";
}



The ParameterModifier stuff was posted somewhere to use the parameters as
out/ref parameters. But it didn't worked out. Using ref in "theMethod"
instead of out didn't work, too. The return value is correct and when the
strToGet strings are set to some strings then these are present in
"theMethod" but changes to str1 and str2 didn't affect strToGet1 and
strToGet2.

I haven't tried it, but from my reading of the documentation the code for
setting up the "mods" variable should be:

ParameterModifier p = new ParameterModifier(2);
p[0] = true;
p[1] = true;
ParameterModifier[] mods = { p };

Chris Jobson
 
G

Gunnar Frenzel

Yes, the one I posted was the last structure I used. I tried the way you wrote it, too, but this doesn't work, too. It
behave just the same way like the version I posted in my previous message.
Gunnar
 
C

Chris Jobson

Gunnar Frenzel said:
Yes, the one I posted was the last structure I used. I tried the way you
wrote it, too, but this doesn't work, too. It behave just the same way
like the version I posted in my previous message.

The problem seems to be that on return from the InvokeMember the Out/Ref
parameters have been updated, but ONLY in the args array. If you want the
original variables changed then you have to copy back the values from the
args array. The following code works fine for me (where my method
ClassLibrary1.Class1.Test takes two "out string" parameters):

string s1 = String.Empty;
string s2 = String.Empty;

Assembly asmblyDll = Assembly.LoadFrom("ClassLibrary1.dll");
Type tDll = asmblyDll.GetType("ClassLibrary1.Class1");
object objDll = asmblyDll.CreateInstance("ClassLibrary1.Class1");

ParameterModifier p = new ParameterModifier(2);
p[0] = true;
p[1] = true;
ParameterModifier[] mods = { p };

object[] args = new object[2];
args[0] = s1;
args[1] = s2;

bool bRet = (bool)tDll.InvokeMember("Test", BindingFlags.InvokeMethod, null,
objDll, args, mods, null, null);

// Must copy Out/Ref parameters back!
s1 = (string)args[0];
s2 = (string)args[1];

if (bRet) MessageBox.Show(s1 + " " + s2);

Chris Jobson
 
G

Gunnar Frenzel

Oh yes, this solved the problem. This works even if no ParameterModifiers are passed.
I tried the overload without ParameterModifier array
bool bRet = (bool)tDll.InvokeMember("theMethod", BindingFlags.InvokeMethod, null, objDll, args);
and passed the values from the args array back to the strings and this worked fine as well.
Thanks a lot.
Gunnar
 
C

Chris Jobson

Gunnar Frenzel said:
Oh yes, this solved the problem. This works even if no ParameterModifiers
are passed.
I tried the overload without ParameterModifier array
bool bRet = (bool)tDll.InvokeMember("theMethod",
BindingFlags.InvokeMethod, null, objDll, args);
and passed the values from the args array back to the strings and this
worked fine as well.

I just noticed that in the documentation for Type.InvokeMember
(http://msdn2.microsoft.com/en-US/library/de3dhzwy.aspx) there is a comment
for the mofifiers parameter: "The default binder does not process this
parameter"! This explains what you've just found (it appears that
ParameterModifier is only used when calling a COM method). Anyway, glad it's
working now.

Chris
 
C

Chris Jobson

Gunnar Frenzel said:
Oh yes, this solved the problem. This works even if no ParameterModifiers
are passed.
I tried the overload without ParameterModifier array
bool bRet = (bool)tDll.InvokeMember("theMethod",
BindingFlags.InvokeMethod, null, objDll, args);
and passed the values from the args array back to the strings and this
worked fine as well.

I just noticed that in the documentation for Type.InvokeMember
(http://msdn2.microsoft.com/en-US/library/de3dhzwy.aspx) there is a comment
for the mofifiers parameter: "The default binder does not process this
parameter"! This explains what you've just found (it appears that
ParameterModifier is only used when calling a COM method). Anyway, glad it's
working now.

Chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top