我創建了將原生utf-8字符串(char *)轉換爲託管字符串的兩種方法,反之亦然。下面的代碼做這項工作:.net中的轉換:原生Utf-8 <->託管字符串
public IntPtr NativeUtf8FromString(string managedString)
{
byte[] buffer = Encoding.UTF8.GetBytes(managedString); // not null terminated
Array.Resize(ref buffer, buffer.Length + 1);
buffer[buffer.Length - 1] = 0; // terminating 0
IntPtr nativeUtf8 = Marshal.AllocHGlobal(buffer.Length);
Marshal.Copy(buffer, 0, nativeUtf8, buffer.Length);
return nativeUtf8;
}
string StringFromNativeUtf8(IntPtr nativeUtf8)
{
int size = 0;
byte[] buffer = {};
do
{
++size;
Array.Resize(ref buffer, size);
Marshal.Copy(nativeUtf8, buffer, 0, size);
} while (buffer[size - 1] != 0); // till 0 termination found
if (1 == size)
{
return ""; // empty string
}
Array.Resize(ref buffer, size - 1); // remove terminating 0
return Encoding.UTF8.GetString(buffer);
}
雖然NativeUtf8FromString是好的,StringFromNativeUtf8一片混亂,但唯一的安全碼我能得到執行。使用不安全的代碼我可以使用一個字節*,但我不想要不安全的代碼。有沒有另一種方法可以讓人想到我不必爲每個包含的字節複製字符串來找到0終止。
我只是添加了取消保存代碼在這裏:
public unsafe string StringFromNativeUtf8(IntPtr nativeUtf8)
{
byte* bytes = (byte*)nativeUtf8.ToPointer();
int size = 0;
while (bytes[size] != 0)
{
++size;
}
byte[] buffer = new byte[size];
Marshal.Copy((IntPtr)nativeUtf8, buffer, 0, size);
return Encoding.UTF8.GetString(buffer);
}
正如你看到它不醜只是需要不安全。
你爲什麼不在意使用'unsafe'代碼? – CodesInChaos
@CodelnChaos:不確定。因爲Procect必須激活對我來說感覺髒的/不安全的開關。 – Totonga
'/ unsafe'開關是相當無意義的。即使不需要開關,Marshal。*也與指針代碼一樣不安全。 – CodesInChaos