How to use a ref string parameter with a Win32 dll?

  • Thread starter Thread starter David Rose
  • Start date Start date
D

David Rose

I am trying to use a string as an in/out parameter from C#.

I have a win32 dll that exports a simple function:

extern "C" __declspec(dllimport) int ShowTheMessage(LPSTR str)
{
MessageBox(NULL, str, "Testing...", MB_OK);
strcpy(str, "XXXXXXXXXXXXXX");

return 42;
}

As a non ref parameter I can pass the string to the dll and the MessageBox()
pops up correctly. If I change it to ref, the MessageBox() comes up with
garbage and I get the following error message:

"An unhandled exception of type 'System.NullReferenceException' occurred in
CSDriver.exe
Additional information: Object reference not set to an instance of an
object."

How do I call this from C#? I have tried Marshaling several different ways,
but no luck.

Thanks for any help.

David Rose
 
Mattias,

I have tried a StringBuilder...

[DllImport("Wrapper.dll")]
static extern void ShowTheMessage(ref StringBuilder bldr);

private void btnTest_Click(object sender, System.EventArgs e)
{
string str = "Testing, testing...";
StringBuilder bldr = new StringBuilder(str, 1000);

ShowTheMessage(ref bldr);
MessageBox.Show(this, str, "After change");
}

The above gives me garbage in the dialog popped up by ShowTheMessage(). If
I take out the ref's, it works fine, but I do not get the change made inside
ShowTheMessage().

David
 
David,

You do not pass the StringBuilder with the "ref" modifier. Remove it,
and it should work.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

David Rose said:
Mattias,

I have tried a StringBuilder...

[DllImport("Wrapper.dll")]
static extern void ShowTheMessage(ref StringBuilder bldr);

private void btnTest_Click(object sender, System.EventArgs e)
{
string str = "Testing, testing...";
StringBuilder bldr = new StringBuilder(str, 1000);

ShowTheMessage(ref bldr);
MessageBox.Show(this, str, "After change");
}

The above gives me garbage in the dialog popped up by ShowTheMessage(). If
I take out the ref's, it works fine, but I do not get the change made inside
ShowTheMessage().

David
 
Nicholas,

I have tried that. The MessageBox() pops up with the correct string, but I
do not get the change in the string that is made in the dll. It only works
with the "in" part.

David


Nicholas Paldino said:
David,

You do not pass the StringBuilder with the "ref" modifier. Remove it,
and it should work.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

David Rose said:
Mattias,

I have tried a StringBuilder...

[DllImport("Wrapper.dll")]
static extern void ShowTheMessage(ref StringBuilder bldr);

private void btnTest_Click(object sender, System.EventArgs e)
{
string str = "Testing, testing...";
StringBuilder bldr = new StringBuilder(str, 1000);

ShowTheMessage(ref bldr);
MessageBox.Show(this, str, "After change");
}

The above gives me garbage in the dialog popped up by ShowTheMessage(). If
I take out the ref's, it works fine, but I do not get the change made inside
ShowTheMessage().

David




Mattias Sjögren said:
David,

How do I call this from C#?

Make the parameter a StringBuilder in C#, not a string.



Mattias
 
Nicholas and Mattias...

My apologies. I was careless.

When I tested the StringBuilder I left the wrong variable in the
MessageBox(). So, I just popped up the String variable that I had used to
create the StringBuilder, not the ToString() method of the StringBuilder.

Thanks for your help.

David




Nicholas Paldino said:
David,

You do not pass the StringBuilder with the "ref" modifier. Remove it,
and it should work.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

David Rose said:
Mattias,

I have tried a StringBuilder...

[DllImport("Wrapper.dll")]
static extern void ShowTheMessage(ref StringBuilder bldr);

private void btnTest_Click(object sender, System.EventArgs e)
{
string str = "Testing, testing...";
StringBuilder bldr = new StringBuilder(str, 1000);

ShowTheMessage(ref bldr);
MessageBox.Show(this, str, "After change");
}

The above gives me garbage in the dialog popped up by ShowTheMessage(). If
I take out the ref's, it works fine, but I do not get the change made inside
ShowTheMessage().

David




Mattias Sjögren said:
David,

How do I call this from C#?

Make the parameter a StringBuilder in C#, not a string.



Mattias
 
Back
Top