Указание кодовой страницы для сортировки строк PInvoke с использованием C#

Я вызываю DLL с помощью PInvoke. Функция DLL возвращает строку C в кодовой странице 437.

Есть ли способ, чтобы маршалинг .Net преобразовывал строку в юникод, или может кто-нибудь предложить, какие параметры я должен указать для DllImport() и MarshalAs() и использовать функцию преобразования для получения вывода в юникоде?

Для справки, это DllImport, который я сейчас использую:

[DllImport("name.dll", CharSet=CharSet.Unicode) ]
internal static extern int GetSweepParam(
    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
);

person Pigrew    schedule 29.12.2009    source источник


Ответы (1)


Маршаллинг строк ANSI всегда использует системную кодировку по умолчанию. Если вы хотите использовать какую-то другую кодировку, вы можете маршалировать эти строки самостоятельно.

[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));
}

Если строка выделена неуправляемой функцией, вы можете маршалировать ее из 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);
}
person Pent Ploompuu    schedule 29.12.2009