.NET System :: Строка в UTF8-байтах, хранящаяся в char * - PullRequest
5 голосов
/ 06 июля 2011

Я заворачиваю неуправляемый код C ++ в проект .NET.Для этого мне нужно преобразовать System::String в UTF8-байты, хранящиеся в char*.

. Я не уверен, что это лучший или даже правильный способ сделать это, и я был бы признателен, если бы кто-то мог взятьПосмотрите и предоставьте отзыв.

Спасибо,

/ David

// Copy into blank VisualStudio C++/CLR command line solution.
#include "stdafx.h"
#include <stdio.h>

using namespace System;
using namespace System::Text;
using namespace System::Runtime::InteropServices;

// Test for calling with char* argument.
void MyTest(const char* buffer)
{
    printf_s("%s\n", buffer);
    return;
}

int main()
{

   // Create a UTF-8 encoding.
   UTF8Encoding^ utf8 = gcnew UTF8Encoding;

   // A Unicode string with two characters outside an 8-bit code range.
   String^ unicodeString = L"This unicode string contains two characters with codes outside an 8-bit code range, Pi (\u03a0) and Sigma (\u03a3).";
   Console::WriteLine(unicodeString);

   // Encode the string.
   array<Byte>^encodedBytes = utf8->GetBytes(unicodeString);

   // Get pointer to unmanaged char array
   int size = Marshal::SizeOf(encodedBytes[0]) * encodedBytes->Length;
   IntPtr pnt = Marshal::AllocHGlobal(size);
   Marshal::Copy(encodedBytes, 0, pnt, encodedBytes->Length);

   // Ugly, but necessary?
   char *charPnt= (char *)pnt.ToPointer();
   MyTest(charPnt);
   Marshal::FreeHGlobal(pnt);

}

1 Ответ

13 голосов
/ 06 июля 2011
  1. Вам не нужно создавать экземпляр кодировщика, вы можете использовать статические экземпляры.

  2. Если вызываемая функция не ожидает указатель накуча HGlobal, вы можете просто использовать простое выделение памяти C / C ++ (new или malloc) для буфера.

  3. В вашем примере функция не становится владельцем, поэтому вам не нужнокопию, просто прикрепите буфер.

Что-то вроде:

// Encode the text as UTF8
array<Byte>^ encodedBytes = Encoding::UTF8->GetBytes(unicodeString);

// prevent GC moving the bytes around while this variable is on the stack
pin_ptr<Byte> pinnedBytes = &encodedBytes[0];

// Call the function, typecast from byte* -> char* is required
MyTest(reinterpret_cast<char*>(pinnedBytes), encodedBytes->Length);

Или, если вам нужна строка с нулевым символом в конце, как и большинство функций C (включаяНапример, в OP) тогда вы, вероятно, должны добавить нулевой байт.

// Encode the text as UTF8, making sure the array is zero terminated
array<Byte>^ encodedBytes = Encoding::UTF8->GetBytes(unicodeString + "\0");

// prevent GC moving the bytes around while this variable is on the stack
pin_ptr<Byte> pinnedBytes = &encodedBytes[0];

// Call the function, typecast from byte* -> char* is required
MyTest(reinterpret_cast<char*>(pinnedBytes));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...