gpt4 book ai didi

.net - 为什么 printf 与托管字符串一起工作?

转载 作者:行者123 更新时间:2023-12-03 14:35:10 26 4
gpt4 key购买 nike

我们目前正在挖掘一些非常古老的 C++/CLI 代码(旧语法 .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 超过了所有编译器检查,并诱使 native 代码使用指向托管堆的指针。自 System::String表示类似于 char - 内存中的数组, printf可能工作。或者编译器转换为 pin_ptr并将其传递给 printf .

我不希望它自动编码 String^char* ,因为如果没有对实际内存地址的任何引用,这会导致内存泄漏。

我们知道这不是一个好的解决方案,后来的 Visual Studio 版本引入的各种编码方法提供了一种更好的方法,但了解这里实际发生的情况会非常有趣。

谢谢!

最佳答案

我相信这是因为编译器正在把它变成这个 IL:

call vararg int32 modopt([mscorlib]System.Runtime.CompilerServices.CallConvCdecl) printf(int8 modopt([mscorlib]System.Runtime.CompilerServices.IsSignUnspecifiedByte) modopt([mscorlib]System.Runtime.CompilerServices.IsConst)*, ..., string)

最后是对 printf 的 pinvoke 调用,因此通过为您编码运行时有点偷偷摸摸。您仍处于托管运行时中,并且运行时将在需要时将编码作为服务提供。

一些注意事项:

看来 clr!GenericPInvokeCalliHelper正在 x86 .NET 4 Workstation CLR 上执行此提升。

the following doesn't work



那是因为那是直接的 C++。它没有机会通过编码,因为它不需要。

关于.net - 为什么 printf 与托管字符串一起工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11831430/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com