views:

53

answers:

2

I'm trying to use a C++ unmanaged dll in a C# project and I'm getting an error when trying to call a function that says that entry point cannot be found.

public class Program
{

    static void Main(string[] args)
    {
        IntPtr testIntPtr = aaeonAPIOpen(0);            
        Console.WriteLine(testIntPtr.ToString());
    }

    [DllImport("aonAPI.dll")]
    public static extern unsafe IntPtr aaeonAPIOpen(uint reserved);
}

Here is the dumpbin for the function:

5    4 00001020 ?aaeonAPIOpen@@YAPAXK@Z

I changed the dll import to [DllImport("aonAPI.dll", EntryPoint="?aaeonAPIOpen")] and [DllImport("aonAPI.dll", EntryPoint="_aaeonAPIOpen")] and no luck.

+2  A: 

It looks like the function you're trying to call is compiled as a C++ function and hence has it's name mangled. PInvoke does not support mangled name. You need to add an extern "C" block around the function definition to prevent name mangling

extern "C" {
  void* aaeonAPIOpen(uint reserved);
}
JaredPar
+2  A: 

Using the undname.exe utility, that symbol demangles to

 void * __cdecl aaeonAPIOpen(unsigned long)

Which makes the proper declaration:

    [DllImport("aonAPI.dll", EntryPoint="?aaeonAPIOpen@@YAPAXK@Z", 
        ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
    public static extern IntPtr aaeonAPIOpen(uint reserved);
Hans Passant
+1, didn't realize you could do that. How safe is this approach? Does the mangled name change from build to build or is it consistent across builds of the same code?
JaredPar
@Jared: the mangling is purely based on the declaration of the C++ function. Which is why undname.exe can work. It's stable as long as the declaration doesn't change. This makes it *safer* than an extern "C" declaration.
Hans Passant