【问题标题】:Handle Pinvoke for 32bit and 64bit DLL [duplicate]处理 32 位和 64 位 DLL 的 Pinvoke [重复]
【发布时间】:2014-11-06 07:11:58
【问题描述】:

我尝试开发一个用于使用 USB 硬件设备的 C# 接口。我通过制造商的 PInvoke 模式访问 API DLL。 有两个同名的 DLL。但一种用于 32 位系统,另一种用于 64 位系统。 我希望我的应用程序为每个系统使用正确的 API。

所以我开始检查正在使用的平台:

bool is64Bit = System.Environment.Is64BitOperatingSystem

我定义了一个字符串变量并设置了推荐.DLL的名称。

像这样:

string dll;
if (is64bit)
{
    dll = "APINAME64.DLL";
}
else
{
    dll = "APINAME32.DLL"
}
[DllImport(dll, SetLastError=true)]
public static extern bool ImmConfigureIME();

但这仍然不起作用。编译器需要一个用于 Pinvoke 的 const 字符串。

有人知道如何解决这个问题吗?

【问题讨论】:

  • 在检查它是否为 64 位后,您尝试过做什么?
  • 我不确定我是否理解您的问题。如果您知道当前系统的位数,是什么阻止您加载正确的 dll?
  • @YuvalItzchakov 我编辑问题。
  • 这里有一些讨论:stackoverflow.com/questions/1573724/…
  • 给它们相同的名称,这样您的 [DllImport] 声明就不必更改。只需重命名文件。然后你只需要帮助 Windows 找到正确的 DLL。这里有许多问题的主题。

标签: c# dll pinvoke 32bit-64bit


【解决方案1】:

您可以在代码中声明这两个 DLL,并为它们指定不同的名称。然后,使用EntryName 属性确保它们有正确的原生 dll 入口点:

[DllImport("APINAME64.dll", EntryName="ImmConfigureIME" SetLastError=true)]
public static extern bool ImmConfigureIME64();

[DllImport("APINAME32.dll", EntryName="ImmConfigureIME" SetLastError=true)]
public static extern bool ImmConfigureIME32();

bool is64Bit = System.Environment.Is64BitOperatingSystem;
if (is64bit)
{
    ImmConfigureIME64();
}
else
{
    ImmConfigureIME32();
}

【讨论】:

  • 感谢您的解决方案。这是一个好主意。但我在非托管 DLL 中使用了 100 多个函数。所以我需要很多额外的代码行来实现。
  • 属性是静态元数据。你不能给他们一个运行时变量作为一个值。为什么不简单地在 NativeMethods 类中声明所有类,封装所有类?
  • 如果您绝对必须在运行时执行此操作。您可以自己拨打LoadLibrary。看看this的问题。
  • 拨打Environment.Is64BitProcess不是更好吗?操作系统可以是 64 位的,但进程是 32 位的。
  • @ShahinDohan OP 希望根据底层操作系统支持加载正确的 DLL,而不是当前进程。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-12
  • 1970-01-01
  • 1970-01-01
  • 2014-08-10
  • 2022-01-20
  • 2011-05-12
  • 2015-01-07
相关资源
最近更新 更多