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.
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
.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With