首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C#本机互操作-为什么大多数库使用LoadLibrary和委托而不是SetDllDirectory和简单的DllImport

C#本机互操作-为什么大多数库使用LoadLibrary和委托而不是SetDllDirectory和简单的DllImport
EN

Stack Overflow用户
提问于 2015-01-16 10:17:39
回答 1查看 2.9K关注 0票数 15

有一个关于如何在运行时设置DllImport搜索目录的DllImport。用两行代码可以很好地工作。

然而,许多开源项目却使用LoadLibrary函数。有“谣言”说通过委托调用本机方法要慢一些。我称它们为“流言”,因为我只在两个地方看到过这种情况,而且这无论如何都是微观优化。

最有趣的地方是这篇博文:http://ybeernet.blogspot.com/2011/03/techniques-of-calling-unmanaged-code.html

在这里,作者衡量了不同技术的表现:

  • C# (信息) 4318毫秒
  • PInvoke -被抑制的安全5415 ms
  • Calli指令5505 ms
  • C++/CLI 6311毫秒
  • 函数委托-被抑制的安全性7788 ms
  • PInvoke 8249 ms
  • 函数委托11594

NNanomsg使用函数委托,但在这条线上提到这篇博客文章时评论道,“这对传统的P/Invoke的性能影响显然不好”。

来自Kestrel服务器的ASP vNext使用了与Libuv库相同的技术:这是代码

我认为使用委托比使用简单的DllImport更麻烦,考虑到性能差异,我想知道为什么面向性能的库使用委托而不是设置dll搜索文件夹?

是否有任何技术上的原因,如安全性,灵活性或其他-或这只是一个品味的问题?我不明白这个理由--难道作者没有搜索StackOverflow就足够了吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-01-16 11:28:14

Hmya,博客文章,这种根本上有缺陷的技术信息分发方式。如果我们能投票给他们,世界就会变得更好。作者在比较苹果和橙子。更像是苹果和自行车。

这里有两种根本不同的互操作场景。第一个是“正常”程序,它是一个在非托管DLL中调用代码的托管程序。使用DllImport属性或C++/CLI是首选的武器。在CLR内部非常优化,它动态地生成机器代码来转换参数并进行调用。重要的是,托管程序总是运行大量的非托管代码,因为它运行在纯非托管操作系统之上。

你所说的“慢”版本,正朝着相反的方向发展。从非托管程序调用托管代码。有些人称其为“反向调用”。这要复杂得多,因为在调用托管代码之前,首先必须加载并初始化CLR。并创建一个应用程序域。并找到并加载包含代码的.NET程序集。JIT编译它。

有三种基本方法可以做到这一点:

  • 自定义主机CLR。这是迄今为止最强大的版本。您可以使用宿主接口显式创建CLR实例,并完全控制其配置。CLRRuntimeHost COM coclass是使这个球滚动的主要工具。
  • 通过向.NET类提供[ComVisible(true)]属性,将它们公开为COM组件。非常简单,非托管代码完全不知道它实际上使用的是.NET代码。默认的CLR主机被加载,COM组件的注册表条目指向mscoree.dll,它在必要时引导CLR。唯一的缺点是非托管代码作者需要编写COM客户端代码,这一技能正在消失。
  • 您正在谈论的是,利用C++/CLI编译器生成DLL导出的能力。也值得注意的是,Robert的非托管导出工具使用了完全相同的技术,但是通过重写程序集注入了这些DLL导出。

第三种方式有很大的缺点,超出了通话的费用。它的扩展性很差,每个方法都必须显式地导出,并且必须是静态的,因此不能实现对象模型。和超级骗子,可怕,肮脏,不可能处理的问题,你无法得到任何诊断时,电话失败。托管代码喜欢抛出异常,如果不是来自代码本身,则从试图告诉您传递错误参数或无法准备代码的CLR中抛出异常。您看不到这些异常,因此无法判断函数是否失败,也无法说明其失败的原因。如果非托管代码没有捕捉到带有非标准__try/_关键字,那么程序就会爆炸。没有任何诊断。即使它确实捕捉到SEH,你也只能得到一个“它不起作用”的信号。

必须编写以这种方式调用的托管代码来处理此问题。它必须包含所有公共方法中的尝试/捕获它们。并记录异常,并提供一种返回错误代码的方法,以便调用方能够检测故障。但是,严重的问题,如缺少依赖all或版本控制问题,根本无法诊断。对于非托管代码作者,简单的LoadLibrary + GetProcAddress来说,这看起来很容易,然而,这是一个长期的支持噩梦。

票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27981719

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档