I have a C++ Dll "TheFoo.dll" with a method "Foo()"
I have access to other C++ code that uses this method by simply calling:
Foo();
I believe the Method does have the:
__declspec( dllexport )
So, with the reading I've done about P/Invoke, i thought i should be able to simply call the same method from my C# code:
namespace PInvokeExample1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
[DllImport(@"C:\MyFolder\TheFoo.dll")]
public static extern
void Foo();
private void button1_Click(object sender, RoutedEventArgs e)
{
Foo();
}
}
}
When i run it, i get an error:
Unable to find an entry point named 'Foo' in DLL 'C:\MyFolder\TheFoo.dll'.
Any ideas why it is not found?
The C++ language supports overloading, much like C# does. You could export an function
void Foo(int)
and a functionvoid Foo(double)
. Clearly those two functions could not both be exported as "Foo", the client of the DLL wouldn't know which one to pick. So it is not.The C++ compiler solves that problem by decorating the name of the function. Adding extra characters that makes a Foo(int) different from a Foo(double). You can see those decorated names by running
Dumpbin.exe /exports foo.dll
from the Visual Studio Command Prompt, that lists the name of the exported functions. Assuming your declaration was relevant, you'd see?Foo@@YAXXZ
.So the corresponding declaration in your C# program should be:
There are ways to change the C++ function declaration to make the C# declaration easier. Which is actually not a good idea, these decorated names actually help catch mistakes.
If you didn't declare it extern "C" in your dll, its name has likely been "mangled". You can use something like Dependency Walker to see what symbols your dll exports.
You should provide more information on your C++. Try using
extern "C" __declspec(dllexport)
instead. C++ exports with strange names so usingextern "C"
avoids that.