Importing C library into Xamarin console project

227 Views Asked by At

So I have the most simple project possible. The entire thing looks like:

enter image description here

main.c

#include "main.h"
int testdejef(int i)
{
    return i+1;
}

main.h

#ifndef __MAIN_H__
#define __MAIN_H__

int testdejef(int i);
#endif

Program.cs

using System;
using System.Runtime.InteropServices;


namespace TestCLib
{
    class MainClass
    {
        [DllImport("libclibjef.a",EntryPoint="testdejef")]
        private static extern int testdejef(int i);

        public static void Main (string[] args)
        {

            Console.WriteLine (testdejef (1).ToString ());
        }
    }
}

Based on the various Xamarin examples on the web, that seems to be mostly right. But it isn't, right now the compilation causes a "System.DllNotFoundException". Note that compiling causes no issues, the debugger does.

I've read trough pages like these: http://developer.xamarin.com/guides/ios/advanced_topics/native_interop/

But documentation seems to be related to Android or iOS code and this issue seems to be Console-application related. Anyone knows the proper way to link a C-Library to the project?

UPDATE: This might be harder than expected. Based on Mono documentation:

Note: Mono uses GLib to load libraries, and GLib has a bug on Mac OS X where it doesn’t use a .dylib extension, but instead uses the Unix .so extension. While this should eventually be fixed, the current workaround is to write a .config file which maps to the .dylib file

As far as I know, console applications dont have an app.config file so instead I compiled the .so into a .dylib but at the moment I'm stuck at that point. The mono page says that the files should be linked in the library lookup folders. I did add the folder to all of the suggested environment variables but that did nothign for me

1

There are 1 best solutions below

2
On

This is easy, but you're not doing it entirely correct. The problem is that you need a dynamic library (libclibjef.dylib), and use that in your DllImport attribute.

It's unclear whether you're building a dynamic library or a static library (libclibjef.a - notice the extension), but in your DllImport you're referencing a static library.

The correct DllImport attribute looks like this:

[DllImport ("libclibjef.dylib")]

and then also make sure you have the dynamic library next to the executable.

If you still have problems, you can run your program from a terminal like this:

export MONO_LOG_LEVEL=debug
export MONO_LOG_MASK=dll
mono --debug yourapp.exe

and you'll get debug output explaining what's going on.