从 .Net 托管代码加载 32 或 64 位 DLL
我有一个非托管 DLL(Scintilla 代码编辑器的 scilexer.dll,由 CodePlex 中的 Scintilla.Net 使用)它是通过 Scintilla.Net 组件从托管应用程序加载的。 Windows 管理的应用程序在 32 位和 64 位环境中运行都没有问题,但我需要创建使用 64 或 32 scilexer.dll 的不同安装。
有没有办法以 32 位和 64 位格式分发 DLL,以便 .Net 框架的 DLL 加载器根据某些 .config 选项或某些“路径名魔术”内容加载 32 或 64 位格式的非托管 DLL?
I have a unmanaged DLL (the scilexer.dll of Scintilla code editor, used by Scintilla.Net from CodePlex) that is loaded from a managed application trough the Scintilla.Net component. The windows managed application runs without problem on both 32 and 64 bit environments, but I need to create different installations that uses the 64 or the 32 scilexer.dll.
Is there a way to distribute both DLLs in 32 and 64 bit format so that the DLL loader of the .Net framework loads the unmanaged DLL in the 32 or 64 bit format depending on some .config option or some "path name magic" stuff?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
P/Invoke 使用 LoadLibrary 加载 DLL,如果已经存在使用给定名称加载的库,LoadLibrary 将返回它。 因此,如果您可以为 DLL 的两个版本指定相同的名称,但将它们放在不同的目录中,则可以在第一次从 scilexer.dll 调用函数之前执行一次类似的操作,而无需重复 extern 声明:
P/Invoke uses LoadLibrary to load DLLs, and if there is already a library loaded with a given name, LoadLibrary will return it. So if you can give both versions of the DLL the same name, but put them in different directories, you can do something like this just once before your first call to a function from scilexer.dll, without needing to duplicate your extern declarations:
不幸的是,我对这个特定的 DLL 一无所知。 然而,当您自己执行 P/Invoke 时,并且您可以处理一些重复,则可以为每个平台创建一个代理。
例如,假设您有以下接口,该接口应由 32 位或 64 位 DLL 实现:
您创建代理:
最后
创建一个为您选择正确代理的工厂:
由于 DLL 是延迟加载的,第一次调用它们时,这实际上是有效的,尽管每个平台只能加载其本机的版本。 有关更详细的说明,请参阅本文。
Unfortunately, I don't know anything about this particular DLL. However, when you do the P/Invoke yourself, and you can cope with a little duplication, it's possible to create one proxy for each platform.
For instance, suppose that you have the following interface, that should be implemented by either a 32 or 64 bit DLL:
You create the proxies:
and
And finally make a factory that picks the right one for you:
As the DLLs are loaded lazily the first time they are being invoked, this actually works, despite each platform only being able to load the version that is native to it. See this article for a more detailed explanation.
我想出的最好的方法如下:
The best I've come up with is the following:
你可以把dll放在system32下。 syswow64中的32位和真实system32中的64位。 对于 32 位应用程序,当访问 system32 时,它们会被重定向到 Syswow64。
您可以在注册表中创建一个条目。 软件密钥有一个名为 Wow6432Node 的子项,32 位应用程序将其视为软件密钥。
这是 powershell 安装程序会执行。
You can put the dll in system32. The 32 bit in syswow64 and the 64 bit in the real system32. For 32 bit application, when thay access system32 they are redirected to Syswow64.
You can create an entry in the registry. The software key has a subkey named Wow6432Node that 32 bit application see as the software key.
Here is what powershell installer does.
非托管 dll 可以与其托管对应项并行安装到 GAC 中。 本文 应该解释它是如何工作的。
Unmanaged dlls can be installed into the GAC side-by-side with their managed counterparts. This article should explain how it works.