开发者

Confused over DLL entry points (entry point not found exception)

I'm trying to learn how to use DLL's in C#. I have a very simple DLL just to test the basics.

// MainForm.cs


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Runtime.InteropServices;

namespace DLL_Test
{
        public partial class Form1 : Form
        {
            [DllImport("TestDLL.dll",
                        EntryPoint="?Add@@YGHHH@Z",
                        ExactSpelling = true,
                        CallingConvention = CallingConvention.StdCall)]
            public static extern int Add(int a, int b);

            public Form1()
            {
                InitializeComponent();
            }

            private void button1_Click(object sender, EventArgs e)
            {
                int num;
                try
                {
                    num = Add(2, 3);
                    richTextBox1.AppendText(num.ToString() + "\n");
                }
                catch (DllNotFoundException ex)
                {
                    MessageBox.Show(ex.ToString());
                }
                catch (EntryPointNotFoundException ex)
                {
                    MessageBox.Show(ex.ToString());
                }
             }
         }
}

And the DLL code:

// TestDLL.cpp

__declspec(dllexport) int __stdcall Add(int a, int b) {
return(a + b);
}

dumpbin returns the following:

ordinal   hint   RVA        name
      1      0   00011005   ?Add@@YGHHH@Z = @ILT+0(?Add@@YGHHH@Z)

This (and other attempts listed below) have all returned the same exception:

System.EntryPointException: Unable to find entry point named "..."

So I am at a loss for how to solve this. Perhaps I do not understand how DllMain functions as the C# entry point for a DLL. TestDLL.dll开发者_StackOverflow works when I test it in a C++ application.

After searching for help, I've attempted the following changes:

// TestDLL.cpp

extern "C" __declspec(dllexport) int __stdcall Add(int a, int b) {
return(a + b);
}

Which results in this from dumpbin

ordinal   hint   RVA        name
      1      0   00011005   _Add@8 = @ILT+135(_Add@8)

Thus, I changed my C# code:

 // MainForm.cs

...

[DllImport("TestDLL.dll",
                        EntryPoint="_Add",
                        ExactSpelling = true,
                        CallingConvention = CallingConvention.StdCall)]
            public static extern int Add(int a, int b);

...

I've also tried __cdecl:

// TestDLL.cpp

extern "C" __declspec(dllexport) int __cdecl Add(int a, int b) {
return(a + b);
}

.

// MainForm.cs

...

[DllImport("TestDLL.dll",
                        EntryPoint="_Add",
                        ExactSpelling = true,
                        CallingConvention = CallingConvention.Cdecl)]
            public static extern int Add(int a, int b);

...

Perhaps I'm misunderstanding the calling conventions. Any help would be very appreciated. Thank you.


use

extern "C" __declspec(dllexport) int __stdcall Add(int a, int b) { ... }

and

[DllImport("TestDLL.dll", CallingConvention = CallingConvention.Stdcall)] 
public static extern int Add(int a, int b); 

extern "C" will prevent name mangling with params and return type such as ?Add@@YGHHH@Z. __stdcall will prepend an _ and add @8 : _Add@8 (where 8 is the total size of arguments). Note that it also affects the way parameters are pushed on the stack.

In your DLLImport statement, since you specify CallingConvention.StdCall, you don't need to specify the name mangling. Just give the regular name (Add) and .NET will take care of name mangling (_Add@8).

Note that you must specify the CallingConvention or .NET wouldn't emit the correct code to push arguments on the stack


The following should work.

Unmanged:

extern "C" __declspec(dllexport) int Add(int a, int b) 
{
    return(a + b);
}

Managed:

class Program
{
    [DllImport("TestDLL.dll")]
    public static extern int Add(int a, int b);

    static void Main()
    {
        Console.WriteLine(Add(1, 2));
    }
}


For future reference: I had a similar problem, solved creating an EMPTY C++ dll project. Probably the standard Visual Studio template causes some trouble.

Refer to this link: http://www.codeproject.com/Articles/9826/How-to-create-a-DLL-library-in-C-and-then-use-it-w

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜