Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interop with native libraries in linux

Tags:

c#

mono

dllimport

I am writing an application in C#, which is cross platform. It uses DllImport for several different libraries. It is also both x32 and x64. It seems to work right for my own compiled .dll/.so. I put the x32 shared libraries in the x32 sub-folder, and the x64 shared libraries in the x64 sub-folder.

On windows via .net framework I call SetDllDirectory("x32" or "x64") depending on the current runtime. On mono, either through windows, linux or mac, I use a DllMap, in RandomLibrary.dll.config. It works fine for files that are located in the x32 or x64 directories.

However, I also use DllImport for libraries that I didn't write, such as FreeType2. On windows, I just shove the built libraries in the two sub-folders. However on linux I would rather use the libfreetype6 library that you can install via your friendly local package manager. I can hardcode the DllMap link to /usr/lib/x86_64-linux-gnu/libfreetype.so.6, but I assume that the freetype file will change depending on what distro you use.

Is there any easy way where it can just find libfreetype.so regardless of what distro I am using?

like image 829
Programmdude Avatar asked Aug 10 '12 04:08

Programmdude


2 Answers

Using DllImport("libfreetype.so.6") for Linux should be enough, as the system should be configured to handle it correctly. Make sure you have the correct packages installed. If it doesn't work you may have a misconfigured system: post the errors you get, the LD_LIBRARY_PATH env var value, the contents of /etc/ld.so.conf and the files in /etc/ld.so.conf.d/. The output of

/sbin/ldconfig -p |grep freetype

would be useful as well.

like image 76
lupus Avatar answered Oct 27 '22 08:10

lupus


Mono have a thing/procedure specifically for this, it is called DllMap. You can specify which unmanaged libaray gets loaded on which platform. Eg:

<configuration>
    <dllmap dll="foobar" os="linux" wordsize="64" target="linux/amd64/libfoobar.so" />
    <dllmap dll="foobar" os="linux" wordsize="32" target="linux/i386/libfoobar.so" />
</configuration>

I've not tried the above myself - The dllmap docs seem to hint that the target value isn't a path but I can't be sure.

Another approach would be to have a simple shellscript or batch file. On linux the shell script could easily work out the architecture by calling arch and set LD_LIBRARY_PATH accordingly. I generally prefer a shell wrapper around my mono programs ( seeing MyProgram.exe on the console feels ugly )

Lastly you might have more fun if you pinvoke into dlopen or LoadLibarary to pre-load your shared libraries.

When your managed app starts you decide what architecture you are and then use dlopen() if on linux or LoadLibaray() if on windows.

like image 40
IanNorton Avatar answered Oct 27 '22 06:10

IanNorton