Alexufo
@Alexufo
противоречивый, сложный, весь компьютерный.

C# — как перевести строку в utf16 и сделать маршалинг?

string ZPLString ="Строка";   
IntPtr pBytes;
pBytes = Marshal.StringToCoTaskMemAnsi(ZPLString );
  • Вопрос задан
  • 2633 просмотра
Пригласить эксперта
Ответы на вопрос 2
chydaya
@chydaya
например, написать структуру с нашей строкой
struct StructWithStr
{
	[MarshalAs(UnmanagedType.ByValTStr, SizeConst = SIZE_CONST)]
	public string OurStr; 
}

заполнить ее нужной строкой
написать хелпер сохранения структуры в указатель
public static class UnMemory<T> where T : struct
{
    public static void SaveInMem(T memoryObject, ref IntPtr ptr)
    {
        if (default(T).Equals(memoryObject))
        {
            // объявляем указатель на кусок памяти
            ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(T)));
            return;
        }
        if (ptr == IntPtr.Zero)
        {
            // объявляем указатель на кусок памяти
            ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(T)));
            // записываем в память данные структуры
            Marshal.StructureToPtr(memoryObject, ptr, false);
	}
        else
        {
            // записываем в память данные структуры
            Marshal.StructureToPtr(memoryObject, ptr, true);
        }
    }
}

передать IntPtr в библиотеку
Ответ написан
Комментировать
@Sumor
Можно воспользоваться преобразованием из string в массив байтов — функция
Encoding.Unicode.GetBytes для UTF16
Encoding.UTF8.GetBytes для Utf8 и тд
При этом нужно не забыть обеспечить в конце строки нулевой символ.
Если строка будет использоваться для COM - выделение памяти через AllocCoTaskMem, если для вызовов неуправляемого кода — AllocHGlobal.
Ну и не забыть освободить память после использования.
var str = "abc\0";
var UTF16data = Encoding.Unicode.GetBytes(str);
var len = UTF16data.Length;
IntPtr pData = Marshal.AllocCoTaskMem(len);
// IntPtr pData = Marshal.AllocHGlobal(len);

… использование pData …

Marshal.Copy(UTF16data, 0, pData, len);
Marshal.FreeCoTaskMem(pData);
// Marshal.FreeHGlobal(pData);
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы