【问题标题】:How to use the correct unmanaged DLL file according CPU architecture? (32 / 64 bits)如何根据 CPU 架构使用正确的非托管 DLL 文件? (32 / 64 位)
【发布时间】:2011-04-08 00:20:38
【问题描述】:

我必须使用来自 ASP.NET 站点的 C++ DLL 文件。该网站将托管在 32 位和 64 位环境中。

我有一个 32 位和 64 位版本的非托管 DLL 文件。如何根据当前服务器架构从正确的方法中导入方法?

就像有人发布的那样,这可以作为部署问题来处理。我担心的是:使用这个 DLL 文件的 Web 应用程序很大,而且我们没有部署文档。没有人会记得部署正确的 DLL 文件,所以我试图从解决方案中消除人为因素 :)

【问题讨论】:

  • 您是否正在尝试调试它?您将符号导入或用于什么?
  • @linuxuser27:不确定我是否理解你的问题。我正在尝试在我的项目中使用 dll,调用一些方法。
  • 我明白了。当您说符号时,通常指的是在编译期间创建的结果 PDB 文件。我会编辑您的问题以避免这种混淆。您是在 .NET 代码中执行 p\invoke 以使用程序集,还是使用托管 C++ 包装器将程序集带入 .NET 项目?
  • @linuxuser27:我将“符号”更改为“方法”。感谢您的建议!我正在使用 [DllImport("unmanaged.dll")]。
  • 如果它们有不同的名称,答案是:很痛苦,您将不得不使用 LoadLibrary 并获取 proc 指针并将它们编组给委托。编辑:我只会编译 2 个版本...

标签: .net c++ 32bit-64bit


【解决方案1】:

要让编译器/框架完成你需要做的大部分工作

  1. 拥有多个构建“平台”(通常是 x86、x64 - 移除 AnyCPU)
  2. 为每个构建配置设置每个“平台目标”配置
  3. 我们添加了条件编译符号__WIN32 & __X64

根据平台列出您的功能的不同实现,包括不同的 dll 名称,如果您需要同时安装两者。

#if __WIN32
        public delegate int Move(int target);
        [DllImport("my.dll", SetLastError = true, CharSet = CharSet.Auto)]
#elif __X64
        public delegate int Move(int target);
        [DllImport("my64.dll", SetLastError = true, CharSet = CharSet.Auto)]
#endif

否则,您可以使用 loadlib 并自己管理编组。

【讨论】:

  • 你绝对不需要自己编组。
  • 现在您不仅有两个非托管 DLL,而且还有两个不同的程序集。问题加倍。
  • 当然,我也不太喜欢它,但到目前为止,我发现的常见建议是您应该使组装处理器特定于特定的处理器,包括在 MSDN/论坛上。
  • 您能发布 MSDN 论坛链接吗?还是那里的版主,我也许可以删除它。
  • MSDN 论坛在此处推荐 SetDllDirectoryLoadLibrary 作为适用于旧 Windows 版本的替代解决方案:social.msdn.microsoft.com/Forums/en/csharpgeneral/thread/…
【解决方案2】:

最简单的方法是在两个不同的目录中为两个本机库提供相同的文件名,然后根据位数为adjust your application DLL search path

http://www.pinvoke.net/default.aspx/kernel32.setdlldirectory

【讨论】:

  • 在加载需要扩展搜索路径的程序集之前,如何安排程序集以便调用此内核函数扩展dll搜索路径?
  • P/invoke 不会导致本机库在导入表中列出,OS 加载程序将在启动时查找它们。相反,它在第一次调用带有特定库名称的任何标记为[DllImport] 的方法时在内部调用LoadLibrary。因此,在声明导入方法的类的类型初始化程序(a/k/a 类构造函数 a/k/a 静态构造函数)中调用 SetDllDirectory 可以保证它会在 p/invoke 尝试加载 DLL 之前发生.
  • 这里有一些其他有用的信息:codeproject.com/Messages/1199816/Re-Yuck.aspx
【解决方案3】:

我们知道我们不能使用添加引用来添加非托管 DLL 文件。因此,我们需要一种替代方法来根据 CPU 架构处理非托管 DLLS 文件,即在您的项目目录中添加 DLL 文件。

  1. 在名为 x32 和 x64 的项目中创建新文件夹。
  2. 根据架构将您的 DLL 文件复制到这些文件夹中。
  3. 选择文件并打开属性,更改“复制到输出目录:始终复制”
  4. 对两个文件夹中的所有文件重复此操作

现在在任何平台上构建项目,当您构建项目时,x86 和 x64 文件夹都将复制到 bin 文件夹中。 当这将在服务器上运行时,它将根据 CPU 架构使用非托管 DLL 文件。

【讨论】:

    猜你喜欢
    • 2015-02-15
    • 2020-08-30
    • 2017-04-01
    • 2010-11-03
    • 2011-01-05
    • 2011-12-22
    • 1970-01-01
    • 2011-05-06
    相关资源
    最近更新 更多