【问题标题】:Mixing 32-bit and 64-bit P/Invokes混合 32 位和 64 位 P/Invokes
【发布时间】:2011-05-22 12:52:49
【问题描述】:

我遇到了一个我很确定我知道答案的问题,但我想我至少会问一下,看看是否有一些“灵丹妙药”可以让我头疼不已。

这是高级视图。

我有一个托管应用程序。此应用程序通过来自不同供应商的第三方库与硬件接口。我对消费托管应用程序拥有完全控制权,对硬件 API 库拥有零控制权。

供应商 A 仅提供 32 位原生 SDK。为了允许我们在 64 位系统上使用它,我们将应用程序标记为在 32 位模式下运行。一切都很好。

我们现在正在与供应商 B 集成,后者在 64 位机器上提供特定于 64 位的本机 API 库。供应商 B 提供的 32 位本机 DLL 无法在 64 位系统上运行(尝试过)。如果我构建一个以 64 位或 AnyCPU 运行的测试工具,它可以正常工作。如果我将它标记为 32 位,它会在 P/Invoke 调用中失败。

似乎供应商 A 和供应商 B 的硬件在 64 位 PC 上将是互斥的,但我想知道是否有人对如何解决这个问题提出建议。

【问题讨论】:

    标签: c# interop 32bit-64bit


    【解决方案1】:

    问题不在于 .NET 或 P/Invoke。这是一个操作系统问题。 64 位进程只能加载 64 位 DLL。 32 位进程只能加载 32 位 DLL。让 32 位应用程序在 64 位 Windows 上运行的神奇 Windows-on-Windows(或 WoW)层存在于用户模式进程(EXE 和 DLL)和内核之间。无法在 64 位进程中运行 32 位 DLL。魔兽世界层存在于其下方。 (基本上,WoW 是 64 位 Win32 API 的 32 位包装器,它在进程的 32 位世界和操作系统的 64 位世界之间编组数据和函数调用。)

    您最好/唯一的选择是在不同的进程中运行您的 32 位和 64 位组件,并使用某种形式的 IPC 进行通信。这具有将您的核心应用程序与可能不稳定的第 3 方组件分离的额外好处。如果第 3 方组件崩溃或行为异常,只需重新启动包含该组件的进程即可。

    【讨论】:

    • 我们已经将它隔离在 anotehr AppDomain 中,所以安全性很好。将其移至其他进程会增加我们希望避免的接口复杂性,但似乎要么放弃供应商 A 的硬件。
    • 很好,您已将其隔离在另一个 AppDomain 中。但是,AppDomain 仅在托管代码组件之间提供安全性。非托管代码可以愉快地抓取一个错误的指针并开始向整个进程内存空间喷射垃圾,而不管 AppDomain 是什么。您可能希望通过内存映射文件或类似技术考虑 IPC,以便第三方组件不会对您的应用程序造成严重破坏。 :)
    【解决方案2】:

    您可以创建一个单独的 32 位进程来与供应商 A 交互,然后使用 WCF 与它进行通信。

    【讨论】:

    • 是的,我试图避免这种情况——但这可能是唯一的办法。
    【解决方案3】:

    由于您无法将 32 位和 64 位图像加载到同一进程中,因此您必须使用多进程解决方案。

    【讨论】:

      【解决方案4】:

      希望有人可以提出更好的替代方案,但也许您可以将其中一个库(与您的应用的带宽连接最低的那个)包装在一个单独的进程中,然后与它通信(例如通过套接字)。

      【讨论】:

        猜你喜欢
        • 2013-01-11
        • 2013-10-23
        • 1970-01-01
        • 2017-02-02
        • 1970-01-01
        • 1970-01-01
        • 2013-12-19
        • 1970-01-01
        • 2015-03-22
        相关资源
        最近更新 更多