代码之家  ›  专栏  ›  技术社区  ›  luiscubal

dllimport不完整的名称

  •  1
  • luiscubal  · 技术社区  · 15 年前

    我在.NET下使用了几个p/invoke。但是,我希望我的库在Windows和Linux中都能工作,最好使用相同的二进制文件。

    因为我所依赖的本机库可以在多个平台上使用,所以我希望将它们与托管库的二进制文件一起使用。

    现在我用的是这样的东西:

    [DllImport("/usr/lib/libMYLIBNAME.so.1")]
    

    但这显然只适用于Linux。我在考虑我可以从/usr/lib中复制该二进制文件,并与我的应用程序一起分发,因此我可以将上面的内容减少到:

    [DllImport("libMYLIBNAME.so")]
    

    但这仍然只是Linux。

    在Linux和Windows上的mylibname.dll下,是否有更改库名称字符串以便查找libmylibname.so的方法,或者类似的方法?

    我想避免任何需要为每个支持的平台重新编译的操作…

    (注意:更好的解决方案是在Windows上查找mylibname.dll,在Linux上查找/usr/lib/libmylibname.so.1,但此改进是可选的)

    3 回复  |  直到 15 年前
        1
  •  7
  •   Chris Taylor    15 年前

    两件事

    1-不带扩展的dllimport 这在Windows、Linux和Mac上受支持,并将为目标平台导入适当的库。

    [DllImport("libMYLIBNAME")] - 
    

    2-首选选项是使用 <dllmap/> 它允许您将导入库名称映射到目标平台库名称。因此,如果在Windows上有一个名为 mylib.dll 相应的Linux也是如此 mylinuxlib.so.3.6.1 可以使用Windows dll名称导入此文件

    [DllImport("mylib.dll")]
    

    并将配置添加到配置中,以将此名称映射到Linux库名称

    <configuration>
      <dllmap dll="mylib.dll" target="mylinuxlib.so.3.6.1" />
    </configuration>
    

    阅读更多信息 Here

        2
  •  2
  •   Steve Danner    15 年前

    我看到的一个解决方案是围绕P/Invokes创建一个抽象包装类,并基于环境生成适当的包装类。

    public abstract class Wrapper
    {
       public void SomeMethod()
       {
          WrappedMethod();
       }
    
       public static Wrapper GetWrapper()
       {
          //TODO: write some method to determine OS
          return IsLinux() ? new LinuxWrapper() : new WindowsWrapper();
       }
    
       public abstract void WrappedMethod();
    }
    
    public class WindowsWrapper : Wrapper
    {
      //windows dll imports go here
    
      public override void WrappedMethod()
      {
          //p/invokes go here
      }
    }
    
    public class LinuxWrapper : Wrapper
    {
      //linux dll imports go here
      public override void WrappedMethod()
      {
         //p/invokes go here
      }
    }
    
        3
  •  2
  •   Hans Passant    15 年前

    Windows对DLL的文件扩展名并不挑剔。更改它们并不罕见,.ocx用于ActiveX控件,.scr用于屏幕保护程序。但仍然是一个常规的动态链接库。Windows加载器从内容验证文件的标识,PE32头文件使其成为真正的DLL。

    所以只需将.dll的窗口版本重命名为.so。更改链接器的输出名称设置或只重命名文件。