简体   繁体   中英

How to marshal a string to a null terminated ascii or utf8 IntPtr

How do I marshal a .net string to a null terminated ascii or utf8 IntPtr. For use on linux when interloping to a c lib.

I'm trying to call a c function with signiture like the following:

void my_function(const char* str)

My c# definition is as follows:

[DllImport("mylib.so)]
public static extern void my_function(IntPtr str);

I'm using an IntPtr for the interop because the native code holds onto the string longer than the duration of the function call. So I need to be able to marshal/pin it myself.

Things I've considered:

  • Marshal.StringToHGlobalUni (seems to do 16 bit characters)
  • Marshal.StringToHGlobalAnsi (ansi is for windows I think)
  • Marshal.StringToCoTaskMemUTF8 (says it uses the Com allocator, which seems wrong as this is not for com interop)
  • Marshal.StringToBSTR (says it's for com interop)
  • Marshal.StringToHGlobalAuto (not sure about this one, says it converts to ansi if required which isn't what I want, also no details on how it decides or what it converts to if it doesn't do ansi)

There is also the option of converting to a ascii or utf8 byte array and then marshalling the resulting array (with a null terminator on the end) but this seem like overkill, especially if one of the string marshalling options does the correct thing.

The correct solution is Marshal.StringToHGlobalAnsi . This is the ANSI version of the Marshal.StringToHGlobalUni function. The ANSI version deals with strings which use char as the underlying character type, whereas the Unicode version deals with wide strings which use wchar_t as the underlying character type. The function names were written with Win32-colored glasses .

From your perspective, you have an unmanaged C routine that expects a C-style string, using char as the underlying character type, so that matches with Marshal.StringToHGlobalAnsi .

Marshal.StringToHGlobalAnsi allocates unmanaged memory for the string, which you can then pass to the C code. Because the memory is allocated on the unmanaged heap, GC pinning is not necessary. Once the C code is done, you will need to free the memory by calling Marshal.FreeHGlobal .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM