简体   繁体   中英

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

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 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.

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM