I want to use a library function that accepts a UTF16-LE string as (const char16_t* str, size_t length)
parameter. The length
parameter needs to be provided only for strings that are not null-terminated. The function will copy the string and work on the copy.
.Net's strings are held in memory as UTF16 - assuming they are stored in little endian encoding, one should be able to pin the string, get at the internal pointer and provide that to this library function without an extra copy, as the library will copy it anyway.
Is this possible, and under what circumstances would it be worth it performance-wise (pinning an object isn't free, I believe)?
(This is in the innermost loop of an app that basically copies tons of strings from A to B, and that copying part is the current bottleneck, so it would make sense to speed this up).
Edit This question is almost a duplicate, which is why I deleted it temporarily. But it's not quite a duplicate of that other question, which asks about accessing the data as const wchar_t*
, whereas what I need is const char16_t*
.
Yes, it can be done.
PtrToStringChars
allows us to access the internal const wchar_t*
without copying. All that's necessary now is a reinterpret_cast
to const char16_t*
:
void useStringInCLib(System::String^ s)
{
pin_ptr<const wchar_t> wch = PtrToStringChars(s);
const char16_t *chars = reinterpret_cast<const char16_t*>(wch);
long charLen = s->Length;
// long byteLen = charLen + charLen; // 2 byte wide characters
use_it(chars, charLen);
}