Runtime: DllImport with specific version

Created on 13 Feb 2017  路  7Comments  路  Source: dotnet/runtime

Hey guys,

I'm trying to run native code by using DllImport. You can take a look here if you want: https://github.com/tinchou/corefx/blob/master/src/System.Data.Odbc/src/Common/System/Data/Common/UnsafeNativeMethods.cs

I was specifying odbc as my dll name, which seemed to work for OSX and also for most Linux distros, but then I found it wasn't working for some that didn't symlink libodbc.so to libodbc.so.2.

I thought I could change it to odbc.2 but it didn't work, so I ended up using odbc.so.2.

Then:

  1. Do we have any document with DllImport's look up conventions? I think it's important to have this if we want anyone to use this feature.
  2. Is there any way I can add the version number but also remove the file extension (.so) so I can reuse this name on OSX? Over there we have to bind to libodbc.2.dylib.

Thanks!

area-System.Runtime.InteropServices documentation

Most helpful comment

This is solved by the new NativeLibrary.SetDllImportResolver API in .NET Core 3.0. This API allows you to supply a custom logic that loads the native library - different versions depending on the platform, etc.

All 7 comments

ping @divega @bricelam @moozzyk @mmitche @MichaelSimons.

cc @janvorli

@yizhang82 This seems related to the thread I started with you a few weeks back.

Right now, there's no way to write PInvoke's to native libraries whose names differ "considerably" on different platforms. We do need to concretely document this, but my understanding is that we do the following when trying to locate the shared library:

  • Try with and without "lib" prefixed to the given name (outside Windows)
  • Try with and without the platform suffix ("so", "dylib", "dll").

If the name differs by more than that, you are out of luck. Your remaining option is to manually load the shared library and function pointers from it (dlopen, dlsym), which is not as complicated as it sounds. I have done that for several projects and it works well. If you do that, you can control the logic used to find the shared library, and can implement a sort of "dllmap-like" policy yourself.

For now I have the library name conditionally included at build time depending on the target platform. It won't be hard to add an OSX-specific setting, but anyway I had to ask if it was possible.

I'm fine if you want to turn this issue into a documentation request.

Thanks!

This is still a problem, IMO and makes it harder to write cross-platform code easily.

seems related to @tmds's dotnet/coreclr#8721

This is solved by the new NativeLibrary.SetDllImportResolver API in .NET Core 3.0. This API allows you to supply a custom logic that loads the native library - different versions depending on the platform, etc.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

bencz picture bencz  路  3Comments

omajid picture omajid  路  3Comments

noahfalk picture noahfalk  路  3Comments

omariom picture omariom  路  3Comments

jamesqo picture jamesqo  路  3Comments