Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DllImport decorated name issue - Unable to find entry point

I have a weird problem I have C++ DLL that I am importing in C# library using DLL import. If I specify entry point, everything works as expected, here is the example:

internal static class UnsafeMethods
{
    [DllImport("GoodSchool.dll", EntryPoint = @"?AddNum@@YAHHH@Z")]
    public static extern int AddNum(int num1, int num2);
}

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(UnsafeMethods.AddNum(4,5));
    }
}

However, if I use a simplfied import like here:

[DllImport("GoodSchool.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int AddNum(int num1, int num2);

I get familiar error message:

Unhandled Exception: System.EntryPointNotFoundException: Unable to find an entry point named 'AddNum' in DLL 'GoodSchool.dll'

I used depends to verify that method is properly exposed, and I decoded notation to verify parameters and naming convention - all seems good.

Function signature in C++ is very simple:

  __declspec(dllexport) int AddNum(int num1, int num2); 

Any suggestions how I can call this method in C# without providing decorated name as EntryPoint? What do I do wrong? I do not want to use "C" export, as my understanding is that decorated function name is perfectly fine to be used with DllImport.

like image 268
Sebastian K Avatar asked Jan 11 '13 03:01

Sebastian K


2 Answers

C++ mangles function names to account for function name overloading. After all, if the DLL had

__declspec(dllexport) int AddNum(int num1); 
__declspec(dllexport) int AddNum(int num1, int num2); 

which would AddNum refer to?

The symbol ?AddNum@@YAHHH@Z is the mangled (a.k.a. decorated) name exposed in the unmanaged DLL.

https://en.wikipedia.org/wiki/Name_mangling#Name_mangling_in_C.2B.2B

Your DLL does not export something called AddNum.

like image 160
Eric J. Avatar answered Oct 04 '22 17:10

Eric J.


The decorated function name is fine to use with DllImport, as you can see by the fact that you're doing it. But that requires you to specify the decorated function name in the import. The undecorated name does not exist as far as the linker (static or dynamic) is concerned -- AddNum is simply not a symbol that your library exposes.

If you instead want to do what you're asking:

call this method in C# without providing decorated name as EntryPoint?

then you cannot allow C++ to mangle the name in the first place. You can either specify the decorated name in DllImport or use extern "C" linkage on the C++ code. You must pick one or the other.

like image 27
Michael Edenfield Avatar answered Oct 04 '22 15:10

Michael Edenfield