I created these two methods to convert Native utf-8 strings (char *) to a managed string and vice versa. The following code does the job:
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); }
While NativeUtf8FromString is fine, StringFromNativeUtf8 is a mess, but the only safe code I could run. Using unsafe code, I could use byte *, but I don't want unsafe code. Is there any other way that someone might think about where I don't need to copy a string for each byte contained in order to find the completion 0.
I just add insecure code here:
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); }
As you can see, its not ugly just unsafe.
source share