By way of a current project, I have had to revisit territories that I hoped were long since Gone and Forgotten.
A land of explicit lifetime management, raw pointers to everything, pointer arithmetic, and variable-length structure layouts that make your head spin off its axis!
Of course, I am talking specifically about C++ and unmanaged code interop ala Visual Studio .NET.
It's been a looonnnng several weeks of dual heaps, pinning pointers and accessing other arcane compiler directives and keywords that can only exist in This Universe.
Want to convert a managed Unicode string to an unmanaged buffer of ANSI characters? Good fucking luck! Obviously possible, but for some reason, there's no one-liner to call for this exteremely common interop task. Just for reference, here is what I ended up with:
void convertStringTo(System::String^ str, char buf[], size_t buflen) {
if(str != nullptr) {
pin_ptr wch = PtrToStringChars(str);
size_t convertedChars = 0;
wcstombs_s(&convertedChars, buf, buflen, wch, _TRUNCATE);
}
}
Many "published" solutions used a scheme that allocated a buffer for the ANSI part using Marshal.StringToWhatever(), but this is just one more piece of IntPtr lifecycle bullshit to manage, and you are shit out-of-luck if you want to just put them into a char[] buffer, aside from a stomach-turning extra buffer copy.
The good news is the other primative types box and unbox like butter, once you know the secret:
Object^ value = ....;
Double^ sx = (Double^)value;
double dx = *sx;
Much less painful. Here is how you can use a managed buffer with unmanaged code:
array^ bufx = gcnew array(BUFSIZE);
...
pin_ptr buf_p = &bufx[0];
That's some awfully strange-looking C++, if'n you ask me; but then again, look at the universe we are working in!
So this is only a pseudo-rant, then?
So don't forget to keep your power dry, and all of your punctuation in order! If you can do that, this stuff will get you back on the Long Road Home in no time....