从 .Net 托管代码加载 32 或 64 位 DLL
题
我有一个非托管 DLL(Scintilla 代码编辑器的 scilexer.dll,由 Scintilla.Net 使用 代码库)是通过 Scintilla.Net 组件从托管应用程序加载的。Windows 管理的应用程序在 32 位和 64 位环境中运行都没有问题,但我需要创建使用 64 或 32 scilexer.dll 的不同安装。
有没有办法以 32 位和 64 位格式分发 DLL,以便 .Net 框架的 DLL 加载器根据某些 .config 选项或某些“路径名魔术”内容加载 32 或 64 位格式的非托管 DLL?
解决方案
P /调用使用LoadLibrary加载DLL和如果已经有装载有一个给定名称的库,将调用LoadLibrary返回它。所以,如果你可以给DLL的两个版本相同的名称,但把它们放在不同的目录中,你可以做这样的事情你的第一个电话从scilexer.dll功能之前只有一次,而无需复制你的外部声明:
string platform = IntPtr.Size == 4 ? "x86" : "x64";
string dll = installDir + @"\lib-" + platform + @"\scilexer.dll";
if (LoadLibrary(dll) == IntPtr.Zero)
throw new IOException("Unable to load " + dll + ".");
其他提示
不幸的是,我不知道这个特殊的DLL什么。但是,当你做的P / Invoke你自己,你可以用一个小的重复处理,有可能为每个平台创建一个代理。
例如,假设你已经如下界面,应当通过或者是32或64位DLL中实现:
public interface ICodec {
int Decode(IntPtr input, IntPtr output, long inputLength);
}
您创建代理:
public class CodecX86 : ICodec {
private const string dllFileName = @"Codec.x86.dll";
[DllImport(dllFileName)]
static extern int decode(IntPtr input, IntPtr output, long inputLength);
public int Decode(IntPtr input, IntPtr output, long inputLength) {
return decode(input, output, inputLength);
}
}
和
public class CodecX64 : ICodec {
private const string dllFileName = @"Codec.x64.dll";
[DllImport(dllFileName)]
static extern int decode(IntPtr input, IntPtr output, long inputLength);
public int Decode(IntPtr input, IntPtr output, long inputLength) {
return decode(input, output, inputLength);
}
}
和最后做出一个工厂,挑选适合你的正确的:
public class CodecFactory {
ICodec instance = null;
public ICodec GetCodec() {
if (instance == null) {
if (IntPtr.Size == 4) {
instance = new CodecX86();
} else if (IntPtr.Size == 8) {
instance = new CodecX64();
} else {
throw new NotSupportedException("Unknown platform");
}
}
return instance;
}
}
由于DLL被延迟加载被调用他们的第一次,这实际工作,虽然每个平台只能够加载原产于它的版本。请参见此文章更详细的解释。
好的,我已经想出了如下:
- 分发我的应用程序与两个Dll名为64 32
- 在主要的启动代码包括如下:
File.Delete(Application.StartupPath + @"\scilexer.dll"); { // Check for 64 bit and copy the proper scilexer dll if (IntPtr.Size == 4) { File.Copy(Application.StartupPath + @"\scilexer32.dll", Application.StartupPath + @"\scilexer.dll"); } else { File.Copy(Application.StartupPath + @"\scilexer64.dll", Application.StartupPath + @"\scilexer.dll"); } }
你可以把dll放在system32下。syswow64中的32位和真实system32中的64位。对于 32 位应用程序,当访问 system32 时,它们会被重定向到 Syswow64。
您可以在注册表中创建一个条目。软件密钥有一个名为 Wow6432Node 的子项,32 位应用程序将其视为软件密钥。
这是什么 powershell安装程序可以.
托管DLL可以安装到GAC侧由端与所管理的对应物。 本文一>应该解释它是如何工作的。