使用 P/Invoke 的缺点是什么
我已经在 .net 框架上度过了一段愉快的时光。在这段时间里,在某些情况下,我使用 P/Invoke 来完成托管代码无法完成的事情。
然而我从来不知道使用它的真正缺点是什么。这也是我尽量不使用它的原因。
如果我用谷歌搜索,我会找到各种关于它的帖子,其中一些描绘了灾难性的画面并建议永远不要使用它。使用一个或多个 P/Invoke 调用的应用程序有哪些主要缺点和问题以及它们何时适用。 (不是从性能角度来看,更多的是“无法从网络共享执行”)?
I'm working already a good time with the .net framework. In this time there were some situations, I used P/Invoke for doing things that I couldn't do with managed code.
However I never knew exactly what the real disadvantages of using it were. That was also the reason why I tried not to use it as far as possible.
If I google, then I find various posts about it, some draw a catastrophic picture and recommend never to use it. What are the major drawbacks and problems of an app that uses one ore more P/Invoke-calls and when do they apply. (not of a performance perspective, more in the manner "could not be executed from a network share")?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
结论:仅当没有托管替代方案或在仅存在非托管库来提供所需速度的性能关键应用程序中才使用。
Conclusion: use only if there's no managed alternative or in performance critical applications where only unmanaged libraries exist to provide the required speed.
您可以在三种不同的场景中使用 P/Invoke,每种场景都会出现(或不会出现)不同的缺点。
您需要使用 .NET Framework 中未提供的 Windows 功能。您唯一的选择是 P/Invoke,而您遇到的缺点是现在您的应用程序只能在 Windows 上运行。
您需要使用其他人提供给您的 C 风格 DLL,并且没有托管的等效项。现在,您必须使用应用程序部署 DLL,并且您会遇到编组时间问题,以及函数声明(例如 IntPtr/int)、字符串编组以及其他人们认为困难的事情中可能出现的错误。
您有一些您编写或控制的旧本机代码,并且您想从托管代码访问它而不移植它。在这里,您遇到了 (2) 的所有问题,但您确实可以选择移植它。我断言,通过移植它会比通过糟糕的 P/Invoking 造成更多的错误。如果您要移植的代码大量调用本机代码(例如 CRT),您也可能会导致更大的性能问题。
我的底线是,虽然 P/Invoke 很重要,但告诉人们避免使用它是一个糟糕的建议。一旦正确,剩下的就是运行时编组成本。这些可能低于移植代码所获得的运行时成本。
There are three different scenarios where you use P/Invoke, and different disadvantages arise (or don't) in each.
You need to use a Windows capability that is not provided in the .NET Framework. Your only choice is P/Invoke, and the disadvantage you incur is that now your app will only work on Windows.
You need to use a C-style DLL provided to you by someone else and there is no managed equivalent. Now you have to deploy the DLL with your app, and you have the problems of marshalling time and possible screwups in your declaration of the function (eg IntPtr/int), string marshalling, and other things people find difficult.
You have some old native code that you wrote or control and you feel like accessing it from managed code without porting it. Here you have all the problems of (2) but you do have the option of porting it instead. I'm going to assert that you will cause more bugs by porting it than you will by P/Invoking badly. You may also cause a bigger perf problem if the code you're porting makes a lot of calls to native code such as the CRT.
My bottom line is that while P/Invoke is non trivial, telling people to avoid it is bad advice. Once you have it right, the runtime marshalling costs are all that remain. These may be less than the runtime costs you would get with porting the code.