Verwirrt über DLL-Einstiegspunkte (entry point not found exception)
Ich versuche zu lernen, wie man DLL ' s in C#. Ich habe eine sehr einfache DLL nur zum testen der basics.
//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());
}
}
}
}
Und der DLL-code:
//TestDLL.cpp
__declspec(dllexport) int __stdcall Add(int a, int b) {
return(a + b);
}
dumpbin liefert die folgenden:
ordinal hint RVA name
1 0 00011005 ?Add@@YGHHH@Z = @ILT+0(?Add@@YGHHH@Z)
Diese (und andere versuche, die unten aufgeführt sind) haben alle nach dem gleichen Ausnahme:
System.EntryPointException: Unable to find entry point named "..."
So, ich bin an einem Verlust für, wie man dieses Problem lösen. Vielleicht verstehe ich nicht, wie DllMain Funktionen als C# Einstiegspunkt für die DLL. TestDLL.dll funktioniert, wenn ich test in einer C++ - Anwendung.
Nach der Suche für die Hilfe, ich habe versucht, die folgenden änderungen:
//TestDLL.cpp
extern "C" __declspec(dllexport) int __stdcall Add(int a, int b) {
return(a + b);
}
Die Ergebnisse in diesem von dumpbin
ordinal hint RVA name
1 0 00011005 _Add@8 = @ILT+135(_Add@8)
So, ich habe mein C# - code:
//MainForm.cs
...
[DllImport("TestDLL.dll",
EntryPoint="_Add",
ExactSpelling = true,
CallingConvention = CallingConvention.StdCall)]
public static extern int Add(int a, int b);
...
Ich habe auch versucht __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);
...
Vielleicht bin ich Missverständnis der Aufrufkonventionen. Jede Hilfe wäre sehr geschätzt. Danke.
- Ist, dass die Nachricht genau? Sehen "..." als name der Funktion, die nicht gefunden werden kann ist sehr seltsam.
- Ich hatte ein Problem mit DllImport und es war ein miss-match auf den Namen der Methode. In meinem Fall war ich den Aufruf "Mouse_event" statt "mouse_event". Da war ich immer der "Einsprungpunkt nicht gefunden" und es kann dazu führen, mehrere verschiedene Meinungen es dauerte eine Weile, um zu lösen. Hoffe, es hilft.
Du musst angemeldet sein, um einen Kommentar abzugeben.
verwenden
und
extern "C"
wird verhindern, dass die name manglings mit Parameter und Rückgabetyp wie?Add@@YGHHH@Z
.__stdcall " voran, ein
_
und fügen Sie@8
:_Add@8
(wo 8 ist die Gesamtgröße der Argumente). Beachten Sie, dass es auch auf die Art, wie Parameter werden auf den stack geschoben.In Ihrem
DLLImport
Aussage, da Sie angebenCallingConvention.StdCall
Sie nicht brauchen, um geben Sie den Namen mangeln. Einfach den regulären Namen (Add
) und .NET aufpassen wird der name mangling (_Add@8
).Beachten Sie, dass Sie muss geben Sie die CallingConvention oder .NETTO würde nicht wieder den richtigen code für push-Argumente auf dem stack
Folgende arbeiten sollten.
Unmanged:
Verwaltet:
__cdecl
standardmäßig .Net erwartet__stdcall
standardmäßig.Für zukünftige Referenz: ich hatte ein ähnliches problem, gelöst, erstellen Sie ein LEERES C++ - dll-Projekt. Wahrscheinlich die standard-Visual Studio-Vorlage verursacht einige Schwierigkeiten.
Unter diesem link: http://www.codeproject.com/Articles/9826/How-to-create-a-DLL-library-in-C-and-then-use-it-w