views:

6042

answers:

2

Given the following C function in a DLL:

char * GetDir(char* path );

How would you P/Invoke this function into C# and marshal the char * properly. .NET seems to know how to do LPCTSTR but when I can't figure out any marshaling that doesn't cause a NotSupportedException to fire when calling this function.

+2  A: 

Try

[DllImport("your.dll", CharSet = CharSet.Ansi)]
string GetDir(StringBuilder path);

string is automatically marshalled to a zero-terminated string, and with the CharSet property, you tell the Marshaller that it should use ANSI rather than Unicode. Note: Use string (or System.String) for a const char*, but StringBuilder for a char*.

You can also try MarshalAs, as in this example.

OregonGhost
+3  A: 

OregonGhost's answer is only correct if the char* returned from GetDir is either allocated in HGlobal or LocalAlloc. I can't remember which one but the CLR will assume that any string return type from a PInvoke function was allocated with one or the other.

A more robust way is to type the return of GetDir to be IntPtr. Then you can use any of the Marshal.PtrToStringAnsi functions in order to get out a string type. It also gives you th flexibility of freeing the string in the manner of your choosing.


[DllImport("your.dll", CharSet = CharSet.Ansi)]
IntPtr GetDir(StringBuilder path);

Can you give us any other hints as to the behavior of GetDir? Does it modify the input string? How is the value which is returned allocated? If you can provide that I can give a much better answer.

JaredPar
Ahhhh.... PtrToStringAnsi was that was what I was looking for, I had figured out to use IntPtr in the meantime, but now I run into one snag...I'm using .NETCF and PtrToStringAnsi is only in full framework :(
Adam Haile
Turns out that OpenNetCF has PtrToStringAnsi....looks like problem solved. Will mark this as accepted as soon as I can test the code.
Adam Haile