I am calling a DLL using PInvoke. The DLL's function returns a C string in codepage 437.
Is there a way to have the .Net marshaling convert the string to unicode, or could someone suggest which parameters I should give to DllImport() and MarshalAs() and a conversion function to use in order to get an output in unicode?
For reference, this is the DllImport that I currently use:
[DllImport("name.dll", CharSet=CharSet.Unicode) ]
internal static extern int GetSweepPar开发者_如何学Cam(
int param_num,
[Out,MarshalAs(UnmanagedType.LPStr)]StringBuilder param_name,
[Out,MarshalAs(UnmanagedType.LPStr)]StringBuilder param_units,
double[] values,
[MarshalAs(UnmanagedType.LPStr)]StringBuilder error_string
);
ANSI string marshalling always uses the system default encoding. If you want to use some other encoding, then you can marshal those strings yourself.
[DllImport("name.dll")]
internal static extern int GetSweepParam(
int param_num,
[Out]byte[] param_name,
[Out]byte[] param_units,
double[] values,
byte[] error_string
);
static void Test()
{
Encoding enc = Encoding.GetEncoding(437);
byte[] param_name = new byte[1000], param_units = new byte[1000];
GetSweepParam(123, param_name, param_units, new double[0], enc.GetBytes("input only"));
string name = enc.GetString(param_name, 0, Array.IndexOf(param_name, (byte)0));
string units = enc.GetString(param_units, 0, Array.IndexOf(param_units, (byte)0));
}
If the string is allocated by the unmanaged function, then you can marshal it from an IntPtr
.
static unsafe string PtrToStringAnsiWithEncoding(IntPtr p)
{
int l = 0;
byte* bytes = (byte*)p.ToPointer();
while(bytes[l] != 0) l++;
char* chars = stackalloc char[l];
int bytesUsed, charsUsed;
bool completed;
Encoding.GetEncoding(437).GetDecoder().Convert(bytes, l, chars, l, true, out bytesUsed, out charsUsed, out completed);
return new string(chars, 0, charsUsed);
}
精彩评论