背景:我的MonoMac应用程序使用自定义版本的sqlite3.0.8.6.dylib。
我需要让MyApp.app使用此dylib的确切步骤。
以下是我采取的一些步骤:
将dylib复制到MyApp.app/Contents/SharedSupport。 (相关问题:这是第三方dylibs的首选位置还是MyApp.app/Contents/Frameworks首选?)
更改了库的已安装名称,使其与新位置匹配。
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)
问题
MonoMac众神会帮助解决一个简单的解决方案吗?我花了几个月,打开和关闭,试图让它工作。
请提供确切的步骤 - 这个问题与细节有关。
答案 0 :(得分:4)
看看我对这个问题的回答: Setting path of the Native Library for DllImport on Mono for Mac
二进制启动程序来自monodevelop/main/build/MacOSX/monostub.m。
您可以使用MyApp.app/Contents/Frameworks
或其他路径,重要的部分不是在[DllImport]
中使用任何路径名,而是使用<dllmap>
添加@executable_path
就像我在其他答案中解释的那样app.config
。
还有一个指向github上的测试应用程序的链接。
详细说明
在MyApp.app
中选择一个路径来安装您的原生dll,例如Contents/SharedSupport/sqlite3.0.8.6.dylib
。
计算从托管程序集所在目录到本机.dll
的相对路径,并将@executable_path
添加到其中。
例如,如果您的托管程序集在
Contents/MonoBundle/MyApp.exe
和原生dll
Contents/SharedSupport/sqlite3.0.8.6.dylib
,那就是
@executable_path/../SharedSupport/sqlite3.0.8.6.dylib
。
使用install_name_tool
将库的已安装名称更改为此相对路径。
将新的MyApp.exe.config
文件添加到项目中,其中包含
<configuration>
<dllmap dll="sqlite" target="@executable_path/../SharedSupport/sqlite3.0.8.6.dylib" />
</configuration>
使用您在步骤2中为target
字段计算的路径。右键单击MonoDevelop中的文件,从上下文菜单中选择“快速属性”,然后启用“复制到输出目录”。这会将文件复制到Contents/MonoBundle
目录中,因此它位于MyApp.exe
旁边。
使用[DllImport ("sqlite")]
在您的代码中引用它。
当其他图书馆引用
时当另一个库,例如Mono.Data.Sqlite.dll
引用它时,它会变得更复杂。
使用与上面相同的步骤,但您需要确定其[DllImport]
中其他库正在使用哪个名称来引用本机库并将其放入<dllimport dll="..." />
。您可以在源代码中查找[DllImport]
语句,也可以在程序集上运行monodis
并搜索pinvokeimpl
,例如:
// 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
文件将如下所示:
<configuration>
<dllmap dll="sqlite3" target="@executable_path/../SharedSupport/sqlite3.0.8.6.dylib" />
</configuration>
答案 1 :(得分:2)
如果您使用单声道,请小心。 @executable_path将返回单声道二进制文件的路径,而不是实际的.EXE可执行文件。这应该与Xamarin一起正常工作。
答案 2 :(得分:1)
您可以尝试手动加载sqlite
dylib
。
[DllImport ("/usr/lib/libSystem.dylib")]
public static extern IntPtr dlopen (string path, int mode);
IntPtr p = dlopen("libsqlite3.0.8.6.dylib", 0);
当然正确地解析了dylib
的路径。