we are currently digging through some really old C++/CLI-Code (Old Syntax .NET Beta) and were a bit surprised to see something like this:
System::String ^source("Test-String");
printf("%s", source);
The program correctly outputs
Test-String
We are wondering, why is it possible to pass the managed string source to printf
- and more importantly: Why does it work? I don't expect it to be some convenience-feature by the compiler because the following doesn't work:
System::String ^source("Test-String");
char pDest[256];
strcpy(pDest, source);
This produces a (somehow expected) compiling error saying that System::String^
can't be converted to const char*
. So my only real explanation is that passing a managed reference to a va_list surpasses all compiler-checks and tricks the native code into using a pointer into the managed heap. Since System::String
is represented similar to a char
-Array in memory, printf
may work. Or the compiler converts to a pin_ptr
and passes that to printf
.
I don't expect it to automatically marshal the String^
to char*
, because that would result in a bad memory leak without any reference to the actual memory address.
We know that this isn't a good solution and the various marshalling methods introduced by the later Visual Studio-Versions provide a way better approach but it would be very interesting to understand what is actually happening here.
Thanks!