C# DLL入口点混淆(未找到入口点异常)
我正在努力学习如何在C#中使用DLL。我有一个非常简单的DLL来测试基础知识C# DLL入口点混淆(未找到入口点异常),c#,c++,visual-studio-2010,dll,C#,C++,Visual Studio 2010,Dll,我正在努力学习如何在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 Sys
// 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)
这(以及下面列出的其他尝试)都返回了相同的异常:
System.EntryPointException: Unable to find entry point named "..."
所以我不知道如何解决这个问题。也许我不明白DllMain是如何作为DLL的C#入口点工作的。当我在C++应用程序中测试它时,TestDL.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#代码:
我也试过\uu cdecl
:
// TestDLL.cpp
extern "C" __declspec(dllexport) int __cdecl Add(int a, int b) {
return(a + b);
}
也许我误解了通话惯例。任何帮助都将不胜感激。谢谢。使用
extern "C" __declspec(dllexport) int __stdcall Add(int a, int b) { ... }
及
extern“C”
将防止名称与参数和返回类型(如?Add)发生冲突@@YGHHH@Z
。
__stdcall将在\uuu
前面加上@8
:_Add@8
(其中8是参数的总大小)。请注意,它还影响将参数推送到堆栈上的方式
在DLLImport
语句中,由于指定了CallingConvention.StdCall
,因此不需要指定名称mangling。只需给出常规名称(Add
),而.NET将处理名称损坏(_Add@8
)
请注意,您必须指定调用约定,否则.NET将不会发出正确的代码来在堆栈上推送参数。以下操作应该有效 无管理:
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));
}
}
<>为将来参考:我遇到了类似的问题,解决了创建一个空的C++ DLL项目。标准VisualStudio模板可能会引起一些问题
请参阅此链接:谢谢您的回复,但不要客气。我实现了上面的精确代码,但仍然收到相同的异常。我在控制台和窗口应用程序中也尝试了这些精确的命令。我的项目设置需要更改吗?@Darin:no,调用约定不匹配。默认情况下,C++是代码>.cDECL < /C>。默认情况下,Net预计<代码>在我的例子中,在.NET和C++调用约定之间有一个不匹配是正确的。消息是否准确?将“…”视为找不到的函数名是非常奇怪的。@GregD我对DllImport有一个问题,该方法名不匹配。在我的例子中,我叫“鼠标事件”而不是“鼠标事件”。由于我得到了“未找到入口点”,并且可能会导致几种不同的意见,所以我花了一段时间来解决。希望能有帮助。
[DllImport("TestDLL.dll", CallingConvention = CallingConvention.Stdcall)]
public static extern int Add(int a, int b);
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));
}
}