TheSHEEEP
TheSHEEEP

Reputation: 3132

DllImport __Internal not working despite correct function setup

Using embedded Mono, I'm trying to execute a very simple C function from within C#.

This is the function in C++ code (in global scope):

extern "C"
{
    static int __attribute__((noinline)) dllImportTest()
    {
        return 66;
    }
}

This is the C# code:

[DllImport("__Internal", EntryPoint="dllImportTest")]
public static extern int dllImportTest();

public void testCFunctions()
{
    int dllImport = dllImportTest();
    System.Console.Write("Got dllImport: " + dllImport + "\n");
}

And this is the error I get:

System.EntryPointNotFoundException: dllImportTest
  at (wrapper managed-to-native) MonoGlue.ATestClass:dllImportTest ()
  at MonoGlue.ATestClass.testCFunctions () [0x0000a] in <9effaf2265b34fbcb9a10abd58c42ed7>:0 

I've been looking at examples and similar problems, but I fail to see what is going wrong. To make sure the C function does not get optimized away, I execute it in the C++ code.
I even prevent inlining, as you can see.

However, still no luck. There must still be something I'm missing.

Upvotes: 0

Views: 1330

Answers (1)

TheSHEEEP
TheSHEEEP

Reputation: 3132

Turns out the dllImportTest function did not appear in the executable due to it being static. Admittedly, a static function in the global namespace makes little sense in most situations anyway.

So replacing this:

extern "C"
{
    static int __attribute__((noinline)) dllImportTest()
    {
        return 66;
    }
}

With this:

extern "C"
{
    int __attribute__((noinline)) dllImportTest()
    {
        return 66;
    }
}

Solves the problem.

The reason is that by making a function in global namespace static, it becomes inaccessible to external compilation units, which makes it inaccessible to C# as well (I had incorrectly assumed that this wouldn't affect the C# access).
Things become a little complicated here, so if you want to inform yourself, go ahead and read about compilation units.

If you do require to access a static function (no matter in which namespace), I recommend the "Internal Call" approach - as seen in the official mono example. It has many other benefits, as well.

Upvotes: 1

Related Questions