DllImport 名称不完整

发布于 2024-09-19 04:12:14 字数 605 浏览 6 评论 0原文

我在 .NET 下使用多个 P/Invoke。但是,我希望我的库能够在 Windows 和 Linux 上运行,最好使用相同的二进制文件。

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

现在我正在使用这样的东西:

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

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

[DllImport("libMYLIBNAME.so")]

但这仍然仅限于 Linux。

是否有办法更改库名称字符串,以便它在 Linux 下查找 libMYLIBNAME.so ,在 Windows 上查找 MYLIBNAME.dll ,或者非常类似的东西?

我想避免任何需要为每个支持的平台重新编译的事情...

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

I am using several P/Invokes under .NET. However, I want my library to work both in Windows and Linux, preferably with the same binaries.

Since the native library I depend on is available on multiple platforms, I was hoping to just have them along with my managed library's binaries.

Right now I'm using something like this:

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

But this obviously only works for Linux. I was considering that I could possibly copy that binary from /usr/lib and distribute along with my application, so I could reduce the above to:

[DllImport("libMYLIBNAME.so")]

But this still is Linux-only.

Is there anyway to change the library name string so it'd look for libMYLIBNAME.so under Linux and MYLIBNAME.dll on Windows, or something very similar?

I would like to avoid anything that requires recompilation for each supported platform...

(Note: even better would be a solution that'd look for MYLIBNAME.dll on Windows and /usr/lib/libMYLIBNAME.so.1 on Linux, but this improvement is optional)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

狂之美人 2024-09-26 04:12:14

两件事

1- 不带扩展名的 DllImport
Windows、Linux 和 MAC 均支持此功能,并将为目标平台导入适当的库。

[DllImport("libMYLIBNAME")] - 

2- 首选选项是使用 ,它允许您将导入库名称映射到目标平台库名称。因此,如果在 Windows 上您有一个名为 mylib.dll 的 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>

阅读更多信息 此处

Two things

1- DllImport without the extension
This is supported on Windows, Linux and MAC and will import the appropriate library for the target platform.

[DllImport("libMYLIBNAME")] - 

2- The preffered option is to use the <dllmap/> which allows you to map an import library name to the target platform library name. So if on Windows you have a dll called mylib.dll and the corresponding Linux so is mylinuxlib.so.3.6.1 you can import this using the windows DLL name

[DllImport("mylib.dll")]

And add a configuration to the config to map this name to the Linux library name

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

Read more Here

虫児飞 2024-09-26 04:12:14

我见过的一种解决方案是围绕 P/Invoke 创建一个抽象包装类,并根据环境生成适当的包装类。

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

One solution I've seen is to create an abstract wrapper class around your P/Invokes and to generate the appropriate one based on environment.

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
  }
}
走野 2024-09-26 04:12:14

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

因此,只需将 Windows 版本的 .dll 重命名为 .so 即可。更改链接器的输出名称设置或仅重命名该文件。

Windows isn't picky about the filename extension for a DLL. Changing them isn't unusual, .ocx for ActiveX controls, .scr for screen savers for example. But still a regular DLL. The Windows loader verifies the identity of the file from the content, the PE32 header is what makes it a true DLL.

So just rename your Window version of the .dll to .so. Change the linker's Output name setting or just rename the file.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文