C# P\Invoke DLL no entry point into C++?

2019-03-02 09:06发布

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?

3条回答
贪生不怕死
2楼-- · 2019-03-02 09:34

The C++ language supports overloading, much like C# does. You could export an function void Foo(int) and a function void 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:

    [DllImport("foo.dll", EntryPoint = "?Foo@@YAXXZ", 
               ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
    private static extern void Foo();

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.

查看更多
仙女界的扛把子
3楼-- · 2019-03-02 09:36

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.

查看更多
ら.Afraid
4楼-- · 2019-03-02 09:51

You should provide more information on your C++. Try using extern "C" __declspec(dllexport) instead. C++ exports with strange names so using extern "C" avoids that.

查看更多
登录 后发表回答