【问题标题】:32 bit dll importing in 64 bit .Net application在 64 位 .Net 应用程序中导入 32 位 dll
【发布时间】:2011-03-03 11:49:20
【问题描述】:

我遇到了问题,从昨天开始我一直在尝试解决它,但没有成功。 我有一个 32 位 Delphi DLL,我想将它导入到 .NET WIN 应用程序中。此应用程序必须在 ANY CPU 模式下构建。当然,会抛出异常 BadImageFormatException,这意味着 64 位应用程序无法加载 x86 DLL。 我四处搜索并找到了一个解决方案,它说我必须做包装,但对我来说并不清楚。谁能告诉我如何解决这个问题,有什么方法可以将 32 位 Delphi DLL 导入到任何 CPU 架构(64 位、32 位)或其他解决方案下构建的程序中?

【问题讨论】:

  • 为什么不将 .NET 应用程序编译为 x86?
  • 为什么它必须被编译为任何 CPU? 32 位应用程序将在 64 位操作系统上运行。
  • @OregonGhost 因为现在是 21 世纪。
  • @sproketboy:21 世纪的现实是,您无法在 64 位应用程序中加载 32 位 DLL,并且无论何时需要这样的 DLL(这几乎总是我工作的地方) ,由于硬件访问或通信要求),您无法编译为 64 位。在几乎所有情况下,您实际上并不需要 64 位。我不认为“现在是 21 世纪”是一个很好的理由;)
  • @OregonGhost 我们的 Java 应用程序可以充分利用 64 位,甚至无需重新编译任何东西。

标签: c# .net delphi 32bit-64bit


【解决方案1】:

您需要做的是在 32 位进程中编写一个承载 32 位 DLL 文件的包装应用程序。

然后,您的 64 位应用程序必须与这个 32 位进程通信,通过网络方式,或通过 COM 对象或类似方法使 DLL 函数可用。

无法在 64 位进程中运行 32 位 DLL,无论您如何努力,都需要在 32 位进程中运行它。

如果不能只为 32 位编译您的应用程序,您别无选择,只能创建一个主机应用程序。

【讨论】:

  • 你能给我任何来源吗?我该怎么做?或者你知道哪里可以有详细的解释吗?非常感谢
  • 我很确定 64 位应用程序也不能使用 32 位 COM 组件,还是我错了?我在使用 32 位 COM 控件之前遇到过这个问题,并且在我将 C# 项目编译为 X86 之前遇到了错误。
  • 不幸的是,这不是我的选择:(
  • 我认为他们可以使用进程外 COM 对象,但我实际上并不知道。 @scatterbraiin,“什么”不适合你?
  • @Lasse V. Karlsen 将我的 C# 项目编译为 X86
【解决方案2】:

一般的想法是用托管的 32 位包装 dll 包装您的(非托管)32 位 DLL 并使其 COM 可见。这允许通过其 COM 接口调用您的包装 DLL。

您可以使用 COM 代理使您的 COM dll 显示为进程外 COM 服务器。 请查看这个 SO 问题以获取有关此主题的更多信息:Access x86 COM from x64 .NET

【讨论】:

    【解决方案3】:

    据我了解,您无法在 64 位应用程序中使用 32 位 DLL。也就是说,您只能为 X86 编译您的应用程序。

    您找到的解决方案可能是关于如何在“任何 CPU”编译的项目中使用 32 位和 64 位版本的 DLL,具体取决于应用程序是在 32 位还是 64 位中运行环境。

    为此,您可以在 C# 中编写两个包装 DLL,一个用于 64 位,一个用于 32 位,并根据您是在 64 位还是 32 位操作系统上运行而使用各自的包装器。

    但是,当您只有一个 32 位 DLL 时,这不起作用。 64 位应用程序不能使用 32 位 DLL,32 位应用程序也不能使用 64 位 DLL。

    因此,您要么需要为 32 位编译应用程序,要么必须创建 64 位版本的 DLL。

    【讨论】:

    • 此时,我只有 DLL(32 位)并且没有机会拥有另一个 DLL - 64 位版本,同时我的 .NET 应用程序必须编译为任何 CPU(考虑 64也有点)。 soo,这个案子没有解决办法吗?
    • 好吧,正如 Lasse V. Karlsen 建议的那样,您可以编写一个单独的 32 位应用程序(不是库!),您可以将其作为一个单独的进程启动并使用进程间通信“与之对话”。跨度>
    【解决方案4】:

    一个解决方案虽然有点混乱,但可能是编写一个单独的 32 位应用程序,您可以与您的 64 位应用程序进行通信,例如您向/从发送命令的控制台应用程序。

    不漂亮,但如果您只需要偶尔调用它,它可能会起作用。

    【讨论】:

    • 我试过了,不完全一样,我写了 Class library,我在其中导入了 Delphi DLL,编译了 x86,然后我将它引用到我的 64 位主应用程序,但仍然没有运气。
    • 因为它是同一个问题,只是更复杂。您的 64 位应用程序也不能使用 32 位类库! Mikael 谈论的是一个 32 位应用程序,您可以通过命名管道或其他 IPC 方法与之通信。
    • 我读到可以通过 IPC 实现,但说实话,我还不太清楚.. 你有没有关于这方面的说明?我需要更多细节,因为这对我来说真的很新鲜
    【解决方案5】:

    只需将您的 .Net 应用程序编译为 Platform x86。它将在 x64 机器上运行,并将使用您的 32 位 DLL。不要在包装上浪费时间。

    【讨论】:

    • 如果底层操作系统是 64 位,则不是一个选项,因为它会吞噬通过操作系统层的异常,您将看不到它们!
    • 您曾梦想过哪种神奇的操作系统配置可以在 64 位操作系统上运行 32 位 .Net 应用程序,但会“吞下”异常...
    • 这不是梦,而是我几个月的发展条件。我有一台 64 位开发机器,如果你为 x86 平台编译,异常会被吞没(来自并行任务,而不仅仅是)。 Visual Studio 仅在输出窗口中显示“第一次出现异常的机会”,显然您不会在运行的客户端应用程序中看到。原因:blog.paulbetts.org/index.php/2010/07/20/…
    • Paul Betts 链接已失效,但 google 缓存有效:webcache.googleusercontent.com/search?q=cache:http://…
    猜你喜欢
    • 2012-03-06
    • 1970-01-01
    • 2014-07-09
    • 1970-01-01
    • 1970-01-01
    • 2011-01-16
    • 1970-01-01
    • 2021-03-10
    • 2012-12-16
    相关资源
    最近更新 更多