我有一个非托管 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侧由端与所管理的对应物。 本文应该解释它是如何工作的。

scroll top