gpt4 book ai didi

c# - 开发人员应该了解与托管代码的互操作性

转载 作者:搜寻专家 更新时间:2023-10-31 01:20:52 26 4
gpt4 key购买 nike

作为 C# 开发人员,我想我们中的许多人都有从托管代码调用非托管代码的经历。

在处理托管代码和非托管代码之间的互操作性时,您遇到过的最困难的问题是什么? (最好给出C++函数签名和C#包装器等代码示例)

由于 visual studio 在处理调用时没有提供高级调试信息,您如何调试运行时错误?

最佳答案

一般来说,如果您对 C 的了解不够,无法正确声明,则很难找到 P/Invoke 声明的权威引用。互联网上有很多错误的声明。典型的陷阱是 VB6 声明,那里有很多很多,其中真正是 int 的参数被声明为 Long。 Long 是 VB6 中的 32 位整数类型,Integer 由于历史原因是 16 位的。

另一个广泛传播的错误是在需要 IntPtr 的地方使用 int。这些声明在 32 位模式下工作正常,但在 64 位模式下表现不佳。特别麻烦的是采用 4 个或更少参数的函数,错误的参数类型不会生成 PInvokeStackImbalance MDA 警告,因为前 4 个函数参数是在 CPU 寄存器中传递的。在作者宣布工作完成后很久,这个错误往往会产生影响,很难回到它并诊断问题。

下一个麻烦是声明和维护 P/Invoke 声明或 C++/CLI 包装器的单调乏味。当非托管 API 很大时,您最终会编写大量的 API。当你犯了微妙的错误时,他们每个人都准备好给你一个难以诊断的运行时错误。

真正困难的互操作是与具有基于 IUnknown 接口(interface)的 COM 服务器。此类服务器没有类型库,因此没有机会使用 Tlbimp.exe 自动生成互操作库。您必须在 C# 代码中重新声明接口(interface),并确保获得正确的 [Guid] 和方法声明。当接口(interface)从基于 IUnknown 的中间接口(interface)继承时,缺少对多重继承的支持需要跳过额外的环节。 this author的问题错误地称为“继承税”。

这些类型的服务器比看起来更常见。例如,您想对 shell (explorer.exe) 执行的任何操作都是基于 IUnknown 的。 Vista 和 Win7 扩展也是如此,顺便说一句,Windows API 代码包巧妙地包装了它们。

是的,错误处理。太多的非托管代码只返回不友好的错误代码,如 E_FAIL 或 E_UNEXPECTED。并且没有实现 IErrorInfo,所以您得到的只是一条无用的通用消息。或返回 BOOL 以指示失败的 API,邀请程序员简单地忽略返回值。以及 AccessViolation 或致命引擎执行错误,非托管代码在你面前爆炸,没有留下任何面包屑来找出问题所在。这不是 C# 互操作特有的,这样的代码对任何人来说都很难使用。

除此之外,让它正常工作通常非常简单。 .NET 中的 P/Invoke 编码器和 COM 互操作支持确实非常出色,并且明显优于其他 VM 中的支持。

关于c# - 开发人员应该了解与托管代码的互操作性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4345536/

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