Dll returning null terminated string, how to handle this ?

G

Guest

Hi,

I have a DLL using stdcall and a function of it is returning a null
terminated string. How do I declare this in C# (VS2005) ?

I try things like:

[DllImport(dllName)]
public static extern [MarshalAs(UnmanagedType.LPStr)] string
Version();

But keep getting syntax errors, so clearly I miss something. I also tryed
char[] but this give me exception error.
 
G

Guest

Hi,

I tryed another approach, to just copy something to a string as argument,
but have also strange result.

char[] ver = new char[21];
ApiDll.Version(ver, 20);

And the dll:

public static class ApiDll
{
[DllImport(dllName)]
public static extern void Version([MarshalAs(UnmanagedType.LPArray)]
char[] c, int len);

In the DLL I see the value given with the call. There I copy the string to
the pointer, but in C# the result value is the same. It seems that a copy is
passed to the dll instead of the pointer.

In the DLL (in Delphi):

procedure Version(c: PChar; Len: integer): PChar; export; stdcall;
begin
c := StrPLCopy(c, 'hihihihi', 10);
end;

But the "hihihi" never visisble in C# calling program.

I tryed with the 'out' argument, but this gives me exception errors. So I
think I have to go back to the return value. But dont kno whow..;.
 
W

Willy Denoyette [MVP]

A "return" pointer must be declared as an IntPtr like this:

public static extern IntPtr Version();

and the IntPtr must be explicitely marshaled by using
Marshal.PtrToStringXXX, where XXX depends on type of string (ansi or
unicode).

Willy.


message | Hi,
|
| I have a DLL using stdcall and a function of it is returning a null
| terminated string. How do I declare this in C# (VS2005) ?
|
| I try things like:
|
| [DllImport(dllName)]
| public static extern [MarshalAs(UnmanagedType.LPStr)] string
| Version();
|
| But keep getting syntax errors, so clearly I miss something. I also tryed
| char[] but this give me exception error.
|
| --
| rgds, Wilfried
| http://www.mestdagh.biz
 
W

Willy Denoyette [MVP]

How does this relate to your previous question?, this looks like a different
function.
Maybe it's time to read the Pinvoke stuff in MSDN, and to to take a look at
the samples too.

Willy.

message | Hi,
|
| I tryed another approach, to just copy something to a string as argument,
| but have also strange result.
|
| char[] ver = new char[21];
| ApiDll.Version(ver, 20);
|
| And the dll:
|
| public static class ApiDll
| {
| [DllImport(dllName)]
| public static extern void
Version([MarshalAs(UnmanagedType.LPArray)]
| char[] c, int len);
|
| In the DLL I see the value given with the call. There I copy the string to
| the pointer, but in C# the result value is the same. It seems that a copy
is
| passed to the dll instead of the pointer.
|
| In the DLL (in Delphi):
|
| procedure Version(c: PChar; Len: integer): PChar; export; stdcall;
| begin
| c := StrPLCopy(c, 'hihihihi', 10);
| end;
|
| But the "hihihi" never visisble in C# calling program.
|
| I tryed with the 'out' argument, but this gives me exception errors. So I
| think I have to go back to the return value. But dont kno whow..;.
|
| --
| rgds, Wilfried
| http://www.mestdagh.biz
 
G

Guest

Hi,

Thank you it works. My second question was because I tryed another way to
get forward. It works but I wonder wy the original value is not changed.
Where have I written to ? I try to explain:

This is my call:
public string version()
{
char[] ver = new char[21];
string v = Marshal.PtrToStringAnsi(ApiDll.Version(ver, 20));
return v + " | " + new string(ver);
}

in v is copied the version witch is copy to it in the DLL. But original
value 'ver' is empty. But both point to same memory location. So where has
code in dll written to ?

[DllImport(dllName)]
public static extern IntPtr
Version([MarshalAs(UnmanagedType.LPArray)] char[] c, int len);

And code in DLL is simple:

function Version(c: PChar; Len: integer): PChar; export; stdcall;
begin
c := StrPLCopy(c, VersionInfo, Len);
Result := c;
end;

c is pointer same pointer as ver in C# calling program. Result is return
value and is same pointer. It is the IntPtr in C# calling program.

But in C# calling program ver is empty. So to witch pointer has DLL copy the
string ?
 
G

Guest

Hi,

I found it. I declared a char[] where it has to be a byte[]. I still get
confused with these 16 bit chars...

now v and ver are same string and second question is solved too :)
 

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