[英]Confused over DLL entry points (entry point not found exception)
I'm trying to learn how to use DLL's in C#. 我正在尝试学习如何在C#中使用DLL。 I have a very simple DLL just to test the basics.
我有一个非常简单的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());
}
}
}
}
And the DLL code: 和DLL代码:
// TestDLL.cpp
__declspec(dllexport) int __stdcall Add(int a, int b) {
return(a + b);
}
dumpbin returns the following: dumpbin返回以下内容:
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.
也许我不明白DllMain如何作为DLL的C#入口点。 TestDLL.dll works when I test it in a C++ application.
TestDLL.dll在我在C ++应用程序中测试时有效。
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 这从dumpbin得到了这个
ordinal hint RVA name
1 0 00011005 _Add@8 = @ILT+135(_Add@8)
Thus, I changed my C# code: 因此,我改变了我的C#代码:
// 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
: 我也试过
__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
. extern "C"
将防止使用params和返回类型进行名称修改,例如?Add@@YGHHH@Z
__stdcall will prepend an _
and add @8
: _Add@8
(where 8 is the total size of arguments). __stdcall将添加
_
并添加@8
: _Add@8
(其中8是参数的总大小)。 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. 在
DLLImport
语句中,由于指定了CallingConvention.StdCall
,因此不需要指定名称mangling。 Just give the regular name ( Add
) and .NET will take care of name mangling ( _Add@8
). 只需给出常规名称(
Add
),.NET将处理名称修改( _Add@8
)。
Note that you must specify the CallingConvention or .NET wouldn't emit the correct code to push arguments on the stack 请注意,您必须指定CallingConvention或.NET不会发出正确的代码来推送堆栈上的参数
For future reference: I had a similar problem, solved creating an EMPTY C++ dll project. 供将来参考:我有类似的问题,解决了创建EMPTY C ++ DLL项目的问题。 Probably the standard Visual Studio template causes some trouble.
可能标准的Visual Studio模板会导致一些麻烦。
Refer to this link: http://www.codeproject.com/Articles/9826/How-to-create-a-DLL-library-in-C-and-then-use-it-w 请参考此链接: http : //www.codeproject.com/Articles/9826/How-to-create-a-DLL-library-in-C-and-then-use-it-w
The following should work. 以下应该有效。
Unmanged: 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));
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.