Laden...

DllImport: EntryPoint Not Found (C#), kein Problem in C++. Liegt es am byte array?

Erstellt von RedEyeSyndrome vor 14 Jahren Letzter Beitrag vor 14 Jahren 6.141 Views
R
RedEyeSyndrome Themenstarter:in
6 Beiträge seit 2009
vor 14 Jahren
DllImport: EntryPoint Not Found (C#), kein Problem in C++. Liegt es am byte array?

Hallo,

beim Portieren eines Programms von C++ nach C# tritt bei mir folgendes Problem auf:
Ich rufe Funktionen einer externen DLL auf. Dies funktioniert bei allen DLL-Funktionen bis auf eine. (In C++ klappt's bei allen).


 [DllImport(@"mydll.DLL", EntryPoint = "TrickyFunction")]
                static extern int TrickyFunction             
                (double[] va1, int va2, int va3, double va4, int va5, int va6, int va7, byte[] va8);

Ich bin mir wirklich sicher, den Funktionsaufruf genau wie in C++ zu machen:


TrickyFunction(va1DoubleArray, va2Int, va3Int, va4Int, va5Int, va6Int, va7Int, va8ByteArray);

Leider bekomme ich den folgenden Fehler:

"Eine nicht behandelte Ausnahme des Typs "System.EntryPointNotFoundException" ist in mydll.dll aufgetreten.
Zusätzliche Informationen: Der Einstiegspunkt TrickyFunction wurde nicht in der DLL mydll.DLL gefunden."

Ich bin deswegen beim byte array misstrauisch, weil diese die einzige Funktion ist, die mit einem solchen aufgerufen wird - und nicht funktioniert. Ich gehe davon aus, dass byte Arrays in C# identisch zu denen in C++ sind, oder liege ich falsch?

Danke für eure Tips.

M
1.439 Beiträge seit 2005
vor 14 Jahren

Hallo,

EntryPointNotFoundException bedeutet der Name "TrickyFunction" wurde in der Dll nicht exportiert.
Wenn es sich um eine C++ Dll Handelt hat der Entwickler vermutlich vergessen ein extern "C" vor die Funktion zu schreiben.
Schau dir mit z.B. Dependency Walker an, welche Funktionen die Dll exportiert.

R
RedEyeSyndrome Themenstarter:in
6 Beiträge seit 2009
vor 14 Jahren

Also,
mit Dependency Walker sehe ich meine "TrickyFunction". Sie wird korrekt exportiert, deswegen kann ich sie ja vom existierenden C++-Projekt auch aufrufen.

Wie gesagt, sehr komisch ist, dass der - anscheinend - identische Funktionsaufruf in C++ funktioniert, in C# aber nicht. Woran könnte das noch liegen?

M
1.439 Beiträge seit 2005
vor 14 Jahren

Steht da auch nur "TrickyFunktion" oder etwas in der Art "?TrickyFunction@@xxx"?

R
RedEyeSyndrome Themenstarter:in
6 Beiträge seit 2009
vor 14 Jahren

Die genaue Ausgabe ist:

_TrickyFunction@32
Entry Point 0x00005170

M
1.439 Beiträge seit 2005
vor 14 Jahren

Was hast du beim DllImport als CallingConvention angegeben? Bin mir jetzt nicht sicher, ob .Net das auflösen kann.
Wie sieht es mit den anderen Funktionen aus, welche die Dll exportiert, sehen die ähnlich aus?
Ansonsten beim DllImport mit Entrypoint den exakten Namen, wie ihn dir DependencyWalker anzeigt verwenden.

643 Beiträge seit 2006
vor 14 Jahren

Kanst ansonsten auch direkt über die Adresse (0x00005170) die funktion aufrufen. Benutze die Marshal Klasse um den Zeiger in ein Delegate zu legen.

M
1.439 Beiträge seit 2005
vor 14 Jahren

Kanst ansonsten auch direkt über die Adresse (0x00005170) die funktion aufrufen. Benutze die Marshal Klasse um den Zeiger in ein Delegate zu legen.

Das ist nicht nötig, einfach bei DllImport das EntryPoint Feld auf den exakten Namen setzten.

643 Beiträge seit 2006
vor 14 Jahren

Einglich nicht bei ihm scheint es aber nicht zu funktionieren...

M
1.439 Beiträge seit 2005
vor 14 Jahren

Ja, weil er vermutlich eine falsche CallingConvention verwendet.

R
RedEyeSyndrome Themenstarter:in
6 Beiträge seit 2009
vor 14 Jahren

Danke für die Antworten, also der Reihe nach...

@marsgk:
Ich benutze bisher die default-CallingConvention. Habe aber jetzt auch andere Werten ausprobiert (winapi, stdcall, cdecl). Der Fehler ist unverändert.

Die anderen Funktionen, die ja funktionieren, sehen im DependencyWalker alle sehr ähnlich aus wie die beschriebene.

Wenn ich den exakten Namen _TrickyFunction@32 als EntryPoint setze, bekomme ich statt "EntryPoint not found" folgenden Fehler:

"Eine nicht behandelte Ausnahme des Typs "System.AccessViolationException" ist in NAL-NL1.dll aufgetreten."

@Ayke: Ich versuche gerade, deinen Vorschlag auszuprobieren, kenne diese Variante aber noch nicht. Es läuft bei mir nicht. Hier mein Code:


[SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
public static Delegate GetDelegateForFunctionPointer(IntPtr ptr, Type t);

Und hier die Compilermeldung:
Fehler CS0501: "xy.xy.GetDelegateForFunctionPointer(System.IntPtr, System.Type)" ist nicht als abstrakt, extern oder partiell gekennzeichnet und muss daher einen Text deklarieren.

M
1.439 Beiträge seit 2005
vor 14 Jahren

Zeig doch mal die Definition der C Funktion und wie du bisher versucht hast diese einzubinden.
Vermutlich stimmen die Parameter nicht überein und deshalb hat .Net die Funktion nicht gefunden.

R
RedEyeSyndrome Themenstarter:in
6 Beiträge seit 2009
vor 14 Jahren

Lieber marsgk,

genau das ist ja mein Problem, dass die Parameter meines Wissens nach korrekt sind, es aber trotzdem nicht funktioniert.

Die Funktionsdefinition der DLL liegt mir nicht vor, da sie von einer externen Quelle kommt. Ich habe mich aber genau an die Import-Anweisung desjenigen Programmierers gehalten (und an den Funktionsaufruf vom funktionierenden C++-Programm). Hier aus seiner Anleitung:


DllImport int WINAPI TrickyFunction( double va1[19], int va2, int va3, int va4, int va5, int va6, int va7, bool va8[19] );

Bei mir habe ich in der letzten Variable byte statt bool verwendet, das macht hier jedoch keinen Unterschied - mit bool geht es auch nicht.

M
1.439 Beiträge seit 2005
vor 14 Jahren

Und wie sieht deine C# Deklaration aus?

R
RedEyeSyndrome Themenstarter:in
6 Beiträge seit 2009
vor 14 Jahren

Was genau meinst du? Am Anfang des Threads habe ich alle Zeilen, in denen die Funktion vorkommt, gepostet - den DllImport-Abschnitt und den Funktionsaufruf. Mehr gibts da nicht.

M
1.439 Beiträge seit 2005
vor 14 Jahren

Ah, das habe ich übersehen.

Warum hast du Parameter va4 als double deklariert? Laut Beschreibung sollte es ein int sein.
Bei bool musst du aufpassen kann 8 bzw. 32 Bits haben, meistens aber 32.