在MonoMac应用程序中包含自定义dll和dylib [英] Including custom dll and dylib in MonoMac app

查看:167
本文介绍了在MonoMac应用程序中包含自定义dll和dylib的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

背景:我的MonoMac应用程序使用sqlite3.0.8.6.dylib的自定义版本.

Background: My MonoMac app uses a custom build of sqlite3.0.8.6.dylib.

我需要确切的步骤来使MyApp.app使用此dylib.

I need the exact steps to have MyApp.app use this dylib.

这是我采取的一些步骤:

Here are some steps I took:

  1. 将dylib复制到MyApp.app/Contents/SharedSupport. (相关问题:这是第三方dylib的首选位置还是MyApp.app/Contents/Frameworks的首选位置?)

  1. Copied the dylib to MyApp.app/Contents/SharedSupport. (Related question: is this the preferred location for 3rd party dylibs or is MyApp.app/Contents/Frameworks preferred?)

更改了库的安装名称,以使其与新位置匹配.

Changed the installed name for the library so that it matches its new location.

MyApp.app/Contents/SharedSupport> otool -L libsqlite3.0.8.6.dylib 
libsqlite3.0.8.6.dylib:
    @executable_path/../SharedSupport/libsqlite3.0.8.6.dylib (compatibility version 9.0.0, current version 9.6.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)

问题

  1. MyApp.app/Contents/MacOS/MyApp没有直接引用dylib,因此我无法使用install_name_tool指向新的库位置.我相信该库是由System.Data.Sqlite.dll引用的.
  2. 我想到了在启动脚本中覆盖DYLD_FALLBACK_LIBRARY_PATH,但是 MonoMac现在使用的是二进制启动器(MyApp.app/Contents/MacOS/MyApp),而不是脚本,因此我很走运
  1. MyApp.app/Contents/MacOS/MyApp does not reference the dylib directly, so I can't use install_name_tool to point to the new library location. I believe that the library is referenced by System.Data.Sqlite.dll.
  2. I thought of overriding DYLD_FALLBACK_LIBRARY_PATH in the launcher script but MonoMac now uses a binary launcher (MyApp.app/Contents/MacOS/MyApp), not a script, so I'm out of luck there.

MonoMac的诸神能否为您提供一个简单的解决方案?我花了两个月的时间 ,试图使它正常工作.

Would the MonoMac gods please help with what must be a simple solution? I've spent a couple of months, on and off, trying to get this to work.

请提供确切的步骤-这个问题是所有细节的问题.

And please provide exact steps - this problem is all about the details.

推荐答案

看看我对这个问题的回答: 设置Mac版Mono上DllImport的本机库

Have a look at my answer to this question: Setting path of the Native Library for DllImport on Mono for Mac

二进制启动器来自 monodevelop/main/build/MacOSX/monostub.m .

您可以使用MyApp.app/Contents/Frameworks或其他路径,重要的是不要在[DllImport]中使用任何路径名,而是使用@executable_path<dllmap>添加到您的app.config中,如我所解释的那样.其他答案.

You can use either MyApp.app/Contents/Frameworks or some other path, the important part is not to use any path names in your [DllImport] but instead add the <dllmap> using @executable_path to your app.config like I explained in that other answer.

在github上还有一个指向测试应用程序的链接.

There's a also a link to a test app on github in there.

详细说明

  1. MyApp.app中选择一个路径来安装您的本机dll,例如Contents/SharedSupport/sqlite3.0.8.6.dylib.

  1. Pick a path inside the MyApp.app to install your native dll, for instance Contents/SharedSupport/sqlite3.0.8.6.dylib.

计算从托管程序集所在目录到本机.dll的相对路径,并在其前添加@executable_path.

Compute the relative path from the directory where the managed assembly is located to the native .dll and prepend @executable_path to it.

例如,如果您的托管程序集在 Contents/MonoBundle/MyApp.exe和其中的本机dll Contents/SharedSupport/sqlite3.0.8.6.dylib,然后是 @executable_path/../SharedSupport/sqlite3.0.8.6.dylib.

For instance, if your managed assembly is in Contents/MonoBundle/MyApp.exe and the native dll in Contents/SharedSupport/sqlite3.0.8.6.dylib, then it's @executable_path/../SharedSupport/sqlite3.0.8.6.dylib.

使用install_name_tool将库的安装名称更改为该相对路径.

Change the installed name of the library to this relative path using install_name_tool.

向您的项目添加一个新的MyApp.exe.config文件,其中包含

Add a new MyApp.exe.config file to your project, containing

<configuration>
  <dllmap dll="sqlite" target="@executable_path/../SharedSupport/sqlite3.0.8.6.dylib" />
</configuration>

将在步骤2中计算出的路径用于target字段.右键单击MonoDevelop中的文件,从上下文菜单中选择快速属性",然后启用复制到输出目录".这会将文件复制到Contents/MonoBundle目录,因此它位于MyApp.exe旁边.

Use the path that you computed in step 2. for the target field. Right-click the file in MonoDevelop, select "Quick Properties" from the context menu and enable "Copy to Output directory". This will copy the file into the Contents/MonoBundle directory, so it sits right next to your MyApp.exe.

使用[DllImport ("sqlite")]在您的代码中引用它.

Use [DllImport ("sqlite")] to reference this in your code.

当另一个库引用它时

当另一个库(例如Mono.Data.Sqlite.dll)引用它时,它将变得更加复杂.

When another library, for instance Mono.Data.Sqlite.dll references it, it get a little bit more complicated.

使用与上述相同的步骤,但是您需要确定其他库在其[DllImport]中使用的名称来引用本机库,并将其放入<dllimport dll="..." />中.您可以在源代码中查找[DllImport]语句,也可以在程序集上运行monodis并搜索pinvokeimpl,例如:

Use the same steps as above, but you need to figure out which name that other library is using in its [DllImport] to reference the native library and put that into the <dllimport dll="..." />. You can either look for the [DllImport] statements in the source code or run monodis on the assembly and search for pinvokeimpl, for instance:

// method line 679
.method assembly static hidebysig pinvokeimpl ("sqlite3" as "sqlite3_create_function" cdecl )
       default int32 sqlite3_create_function (native int db, unsigned int8[] strName, int32 nArgs, int32 nType, native int pvUser, class Mono.Data.Sqlite.SQLiteCallback func, class Mono.Data.Sqlite.SQLiteCallback fstep, class Mono.Data.Sqlite.SQLiteFinalCallback ffinal)  cil managed preservesig 
{
    // Method begins at RVA 0x0
} // end of method UnsafeNativeMethods::sqlite3_create_function

因此Mono.Data.Sqlite.dll使用"sqlite3"来引用本机dll,因此您的MyApp.exe.config文件将如下所示:

So Mono.Data.Sqlite.dll is using "sqlite3" to reference the native dll, so your MyApp.exe.config file will look like this:

    <configuration>
      <dllmap dll="sqlite3" target="@executable_path/../SharedSupport/sqlite3.0.8.6.dylib" />
    </configuration>

这篇关于在MonoMac应用程序中包含自定义dll和dylib的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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