CPU架构独立的P / Invoke:能否DLLNAME或路径是"动态"? [英] CPU Architecture Independent P/Invoke: Can the DllName or path be "dynamic"?

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

问题描述

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

我正在加载大量的方法签名从本地的dll,从第三方供应商,在这种情况下,用户空间的接口DLL到硬件的应用程序。该供应商现在已经开始提供该DLL的两个x86和x64版本,现在,我想我的应用程序将受益于运行作为一个64位的过程。除了这一个DLL,一切都是.NET code,使建筑为任何CPU是可行的。

所有方法签名在机DLL的是在64位的相同,在DLL的但是名称是不同的(Foo.dll与Foo_x64.dll)。有什么办法或者通过在P / Invoke的签名或app.config中的条目,我可以把它挑选其中加载DLL的基础上运行的CPU架构?

如果不是不同的DLL名称是在不同的文件夹名称相同,这是否打开任何其他的选择吗?

注:由于这是至关重要的,这个用户空间的DLL版本匹配的硬件安装的内核驱动程序,DLL没有捆绑我们的应用程序,而是我们依赖于供应商的安装程序将其放置在一个目录在%PATH%。

解决方案
  

如果不是不同的DLL名称是在不同的文件夹名称相同,这是否打开任何其他的选择吗?

也许这会为你工作:

 公共静态类NativeMethods
{
  //这里我们只需要使用美孚,并在运行时,我们加载Foo.dll动态
  //从磁盘上的任意路径取决于你想要实现的逻辑
  [的DllImport(富,入口点=酒吧)
  私人无效杆();

  [的DllImport(kernel32中)
  私人不安全的静态外部无效*调用LoadLibrary(字符串的Dllname);

  [的DllImport(kernel32中)
  私人不安全的静态外部无效FreeLibrary则(void *的句柄);

  私人密封不安全类LibraryUnloader
  {
    内部LibraryUnloader(void *的句柄)
    {
      this.handle =手柄;
    }

    〜LibraryUnloader()
    {
      如果(处理!= NULL)
        FreeLibrary则(手柄);
    }

    私人无效*手柄;

  } // LibraryUnloader

  私人静态只读LibraryUnloader卸载;

  静态NativeMethods()
  {
    字符串路径;

    如果(IntPtr.Size == 4)
      路径=路径/到/的/ 32 /位/ Foo.dll;
    其他
      路径=路径/到/的/ 64 /位/ Foo.dll;

    不安全
    {
      void *的句柄=调用LoadLibrary(路径);

      如果(处理== NULL)
        抛出新DllNotFoundException(无法找到原生富库:+路径);

      卸载=新LibraryUnloader(手柄);
    }
  }
}
 

具体做法是在明确地加载其P之前完整路径的本地库/调用自己尝试进行加载。

你怎么看?

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

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.

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?

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

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%.

解决方案

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

Maybe this would work for you:

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);
    }
  }
}

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

What do you think?

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

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆