C# 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

我正在努力学习如何在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)
这(以及下面列出的其他尝试)都返回了相同的异常:

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