本文介绍了CPU 架构独立 P/Invoke:DllName 或路径可以是“动态的"吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法让 P/Invoke (DllImport) 签名引用的特定 DLL 依赖于 CPU 架构?

Is there a way to have the particular DLL referenced by a P/Invoke (DllImport) signature depend on the CPU architecture?

我正在开发一个应用程序,该应用程序从第三方供应商的本机 dll 加载大量方法签名,在本例中是用户空间接口 DLL 到一块硬件.该供应商现在已经开始提供 x86 和 x64 版本的 DLL,我认为我的应用程序将受益于作为 64 位进程运行.除了这个 DLL,一切都是 .NET 代码,因此构建为任何 CPU"都可以.

I'm working on an application that loads a large number of method signatures from a native dll from a third party vendor, in this case the user-space interface DLL to a piece of hardware. That vendor has now started supplying both x86 and x64 versions of the DLL now, and I think my app would benefit from running as a 64bit process. Except for this one DLL, everything is .NET code, so building as "Any CPU" would work.

本机 DLL 中的所有方法签名在 64 位上都相同,但是 DLL 的名称不同(Foo.dll 与 Foo_x64.dll).有什么办法可以通过 P/Invoke 签名或 app.config 条目让它根据正在运行的 CPU 架构选择要加载的 DLL?

All of the method signatures in the native DLL are the same on 64bit, however name of the DLL is different (Foo.dll vs. Foo_x64.dll). Is there any way through either the P/Invoke signatures or app.config entries I can get it to pick which DLL to load based on the running CPU architecture?

如果不是不同的 DLL 名称而是不同文件夹中的相同名称,是否会打开任何其他选项?

If instead of different DLL names it was the same name in different folders, does that open any other options?

注意:因为此用户空间 DLL 的版本必须与已安装的硬件内核驱动程序相匹配,所以 DLL 未与我们的应用程序捆绑在一起,而是依赖于供应商安装程序将其放置在一个目录中在 %PATH% 中.

NB: Because it is essential that the version of this user-space DLL match the installed kernel driver for the hardware, the DLL is not bundled with our app, but instead we depend on the vendor installer to place it in a directory in the %PATH%.

推荐答案

也许这对你有用:

public static class NativeMethods
{
  // here we just use "Foo" and at runtime we load "Foo.dll" dynamically
  // from any path on disk depending on the logic you want to implement
  [DllImport("Foo", EntryPoint = "bar")]
  private void bar();

  [DllImport("kernel32")]
  private unsafe static extern void* LoadLibrary(string dllname);

  [DllImport("kernel32")]
  private unsafe static extern void FreeLibrary(void* handle);

  private sealed unsafe class LibraryUnloader
  {
    internal LibraryUnloader(void* handle)
    {
      this.handle = handle;
    }

    ~LibraryUnloader()
    {
      if (handle != null)
        FreeLibrary(handle);
    }

    private void* handle;

  } // LibraryUnloader

  private static readonly LibraryUnloader unloader;

  static NativeMethods()
  {
    string path;

    if (IntPtr.Size == 4)
      path = "path/to/the/32/bit/Foo.dll";
    else
      path = "path/to/the/64/bit/Foo.dll";

    unsafe
    {
      void* handle = LoadLibrary(path);

      if (handle == null)
        throw new DllNotFoundException("unable to find the native Foo library: " + path);

      unloader = new LibraryUnloader(handle);
    }
  }
}

它包括在 P/Invoke 本身尝试加载它之前显式加载带有完整路径的本机库.

It consists in explicitly loading the native library with its full path before P/Invoke itself tries to load it.

你怎么看?

这篇关于CPU 架构独立 P/Invoke:DllName 或路径可以是“动态的"吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-23 07:17