Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Marshal "char *" in C#

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.

like image 319
Adam Haile Avatar asked Oct 02 '08 15:10

Adam Haile


2 Answers

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.

like image 62
JaredPar Avatar answered Oct 30 '22 16:10

JaredPar


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.

like image 16
OregonGhost Avatar answered Oct 30 '22 16:10

OregonGhost