I am working with a C DLL and have trouble with marshalling strings using P/Invoke.
The DLL has a struct as follows:
typedef struct
{
char sAddress[256];
BYTE byUseRtsp;
WORD wPort;
}INFO,*LPINFO;
My C# struct looks like this:
[StructLayout(LayoutKind.Sequential)]
public struct INFO
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string sAddress;
public byte byUseRtsp;
public short wPort;
}
The string marshalling for sAddress
works with ASCII text, but the DLL uses UTF-8 encoding throughout. So as soon as multi-byte characters are used the marshalling garbles the text. Using CharSet.Unicode
doesn't work here as that tells the marshaller to encode/decode strings as UTF-16 on Windows. I need a CharSet.Utf8
which unfortunately doesn't exist.
I do have a workaround, but it's ugly and want to avoid if possible. The workaround is to replace:
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string sAddress;
with:
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
public byte[] sAddress;
and then just re-write my code to use Encoding.UTF8.GetBytes/String()
methods to get the string values. I will also need to handle null-terminators myself with this method.
Is there a better way of doing this?