Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CA2101: Specify marshaling for P-Invoke string arguments

I am trying to expose a C function which takes a UTF-8 string to C# (dotnet 5.0). I am getting a warning which does not make sense to me. Here is a simple way to reproduce it, using fopen(3):

[DllImport("libc.so.6", CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr fopen([MarshalAs(UnmanagedType.LPUTF8Str)] string pathname, string mode);

Visual Studio 2019 is reporting a warning:

enter image description here

From the documentation, it seems I need to set CharSet.Ansi in my case:

  • https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.charset?view=net-5.0

and use UnmanagedType.LPUTF8Str:

  • https://learn.microsoft.com/en-us/dotnet/framework/interop/default-marshaling-for-strings#strings-used-in-platform-invoke

What did I misunderstood from the documentation ?

like image 469
malat Avatar asked Oct 19 '25 15:10

malat


1 Answers

Technically this is somewhat a duplicate of:

  • https://stackoverflow.com/a/13369930/136285

which suggests to add BestFitMapping = false, ThrowOnUnmappableChar = true

In my case the suggested code 'Show potential fixes' ([MarshalAs(UnmanagedType.LPWStr)]) was just bogus (but that is a different issue).

So correct solution is:

[DllImport("libc.so.6", CharSet = CharSet.Ansi, ExactSpelling = true, BestFitMapping = false, ThrowOnUnmappableChar = true, CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr fopen([MarshalAs(UnmanagedType.LPUTF8Str)] string pathname, string mode);
like image 53
malat Avatar answered Oct 21 '25 05:10

malat



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!