困惑的DLL入口点(入口点未找到exception)

我正在尝试学习如何在C#中使用DLL。 我有一个非常简单的DLL只是为了测试基础知识。

// 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()); } } } } 

和DLL代码:

 // TestDLL.cpp __declspec(dllexport) int __stdcall Add(int a, int b) { return(a + b); } 

dumpbin返回以下内容:

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

这(以及下面列出的其他尝试)都返回了相同的exception:

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

所以我对如何解决这个问题感到茫然。 也许我不明白DllMain如何作为DLL的C#入口点。 当我在C ++应用程序中测试它时,TestDLL.dll工作。

在寻求帮助后,我尝试了以下更改:

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

这是从dumpbin得到的

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

因此,我改变了我的C#代码:

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

我也试过__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); ... 

也许我误解了召唤惯例。 任何帮助将非常感激。 谢谢。

使用

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

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

extern "C"将阻止使用params和返回类型进行名称修改,例如?Add@@YGHHH@Z __stdcall将添加_并添加@8_Add@8 (其中8是参数的总大小)。 请注意,它还会影响参数在堆栈上的推送方式。

DLLImport语句中,由于指定了CallingConvention.StdCall ,因此不需要指定名称mangling。 只需给出常规名称( Add ),.NET将负责名称修改( _Add@8 )。

请注意,您必须指定CallingConvention或.NET不会发出正确的代码来推送堆栈上的参数

以下应该有效。

Unmanged:

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

管理:

 class Program { [DllImport("TestDLL.dll")] public static extern int Add(int a, int b); static void Main() { Console.WriteLine(Add(1, 2)); } } 

供将来参考:我有类似的问题,解决了创建EMPTY C ++ DLL项目的问题。 可能标准的Visual Studio模板会导致一些麻烦。

请参考此链接: http : //www.codeproject.com/Articles/9826/How-to-create-a-DLL-library-in-C-and-then-use-it-w