Have a look at my answer to this question:
Setting path of the Native Library for DllImport on Mono for Mac
The binary launcher comes from monodevelop/main/build/MacOSX/monostub.m.
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.
There's a also a link to a test app on github in there.
Detailed Instructions
Pick a path inside the MyApp.app
to install your native dll, for instance Contents/SharedSupport/sqlite3.0.8.6.dylib
.
Compute the relative path from the directory where the managed assembly is located to the native .dll
and prepend @executable_path
to it.
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
.
Change the installed name of the library to this relative path using install_name_tool
.
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>
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
.
Use [DllImport ("sqlite")]
to reference this in your code.
When another library references it
When another library, for instance Mono.Data.Sqlite.dll
references it, it get a little bit more complicated.
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
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>