C++/CLI中是否有与C#的unsafe等效的功能?

4

我正在尝试将C++/CLI代码移植到可验证的类型安全的C++/CLI代码(使用clr:safe标志),以便可以得到一个AnyCPU程序集。 我遇到的主要编译问题是,我得到了很多C4956错误,我认为可以通过明确告诉编译器我希望它是不安全的来解决这个问题。 有什么建议吗?


4
据我所知,整个语言在很大程度上是相当等效的... - user541686
2
抱歉造成困惑,我稍微更新了一下我的问题。@shf301:实际上我是指/clr:safe,这样它将生成一个仅包含MSIL的程序集。 - Anzurio
只是想澄清一下,我认为你的意思是警告,而不是错误C4956 - Gustavo Mori
@Gustavo:从那个页面上看:“此警告被视为错误”。 - Ben Voigt
哦,嗯,没注意到。谢谢! - Gustavo Mori
显示剩余2条评论
4个回答

2

将不安全的C#代码移植到CLI应该不会遇到太多问题,只要确保使用IntPtr,这是一个符合CLS标准且架构无关的指针。

如果您遇到特定的问题或对某些事情不确定,请更新问题并提供更多细节。


当然,你应该已经在C#中使用IntPtr了,所以我不太确定这个变化在哪里。 - Cody Gray
@Cody 我了解这一点,这就是为什么一般的回答是“你不应该因为不安全代码块的限制而遇到任何问题”,假设他正在使用 IntPtr,而不是像“int a = 4; ((int)&a) = 1;”这样的东西... 这是在陈述显而易见的事实,但这是一个非常模糊的问题。 - Brandon Moretz
这不是批评;只是看起来你在暗示 IntPtr 在 C# 中不会被使用。我同意几乎没有问题移植代码。 - Cody Gray

2

C++/CLI 可以自由地与 C++ 代码混合使用,本质上是不安全的,因此除了语言本身之外,不需要其他等效物。使用 pin_ptr 固定垃圾回收对象和缓冲区,现在您可以使用类似于 C++ 的指针。您还可以在这些指针上使用 C++ STL、不安全转换等。


他正在使用/clr:safe编译器选项,这会防止使用大多数这些功能。 - Ben Voigt
他补充说,在我的回答之后。无论如何,他可以通过使用#pragma来解决这个问题。 - Ed Bayiates

2

这个已经在这里有讨论。

基本上,/clr:pure应该提供的是这个,因为它也会生成一个纯的MSIL程序集。不幸的是,它仍然会导致与特定位数的依赖性,因此不兼容AnyCPU


实际上,代码本身并没有导致 MSIL 不兼容(除非您调用 interop);而是各种库(MFC、ATL、CRT)导致了问题。如果您愿意放弃这些库(和 interop),那么您可以轻松拥有一个 C++/CLI AnyCPU /clr:pure 模块。请参见 https://dev59.com/C1nUa4cB1Zd3GeqPYj5U#9004833。 - Glenn Slayden
正如你在答案中所提到的,编译器和链接器仍会生成带有锁定位数的汇编代码。无法让编译器生成不安全的 AnyCPU 汇编,您需要使用像 corflags 这样的外部工具。 - Ben Voigt

1

关于回答这个问题,我们提供以下参考:

/clr:safe 创建一个仅包含 MSIL 的可验证程序集。您的代码中不能有本地类型,如果尝试使用它们,编译器将抛出错误。此编译模式生成的程序集与 C#(常规模式)和 VB.NET 生成的程序集相同。

为了使用类型安全的代码,您需要使用句柄(使用 gcnew)而不是指针(使用 new)

此外,safe_cast 运算符是 C++/CLI 中的新内容,取代了旧语法中的 __try_cast。safe_cast 保证产生可验证的 MSIL。您可以在通常使用 dynamic_cast、reinterpret_cast 或 static_cast 的任何地方使用 safe_cast。在运行时,safe_cast 检查转换是否有效

您应该获取一份:C++/CLI in Action by Nishant Sivakumar非常好的 C++/CLI 参考资料


safe_cast 只是 static_cast 的替代品,绝对不能替代 dynamic_cast - ildjarn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接