.net - example - encoding utf-8 c#
.NET System:: String a UTF8-bytes almacenado en char* (1)
Estoy envolviendo un código C ++ no administrado dentro de un proyecto .NET. Para esto necesito convertir System::String
en UTF8-bytes almacenados en char*
.
No estoy seguro de si esta es la mejor o incluso la forma correcta de hacerlo y agradecería que alguien pudiera echar un vistazo y proporcionar comentarios.
Gracias,
/ 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);
}
No necesita crear una instancia de codificador, puede usar las instancias estáticas.
Si la función llamada no espera un puntero al almacenamiento dinámico de HGlobal, simplemente puede usar la asignación de memoria simple de C / C ++ (nueva o malloc) para el almacenamiento intermedio.
En su ejemplo, la función no se apropia, por lo que no necesita una copia, simplemente fije el búfer.
Algo como:
// 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);
O si necesita que la cadena termine con cero como la mayoría de las funciones C (incluido el ejemplo en el OP), entonces probablemente debería agregar un byte cero.
// 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));