困惑的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