Reputation: 3132
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
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