我们目前正在研究一些非常古老的 C++/CLI 代码(Old Syntax .NET Beta),看到这样的东西有点惊讶:
System::String ^source("Test-String");
printf("%s", source);
程序正确输出
Test-String
我们想知道,为什么可以将托管字符串源传递给printf
- 更重要的是:它为什么有效?我不希望它成为编译器的一些便利功能,因为以下内容不起作用:
System::String ^source("Test-String");
char pDest[256];
strcpy(pDest, source);
这会产生一个(以某种方式预期的)编译错误,指出System::String^
无法转换为const char*
. 所以我唯一真正的解释是,将托管引用传递给 va_list 会超越所有编译器检查,并欺骗本机代码使用指向托管堆的指针。由于在内存System::String
中表示类似于char
-Array,因此printf
可能会起作用。或者编译器转换为 apin_ptr
并将其传递给printf
.
我不希望它自动编组String^
to char*
,因为这会导致严重的内存泄漏,而没有任何对实际内存地址的引用。
我们知道这不是一个好的解决方案,后来的 Visual Studio 版本引入的各种编组方法提供了一种更好的方法,但了解这里实际发生的事情会非常有趣。
谢谢!