Laden...

DLL (C++) in C# einbinden: Unable to find an entry point named 'X' in DLL 'y.dll'

Erstellt von Catwiesl vor 13 Jahren Letzter Beitrag vor 13 Jahren 2.897 Views
C
Catwiesl Themenstarter:in
7 Beiträge seit 2010
vor 13 Jahren
DLL (C++) in C# einbinden: Unable to find an entry point named 'X' in DLL 'y.dll'

Hallo,

ich versuche eine in C++ erstellte DLL in C# einzubinden und darin eine Funktion aufzurufen.

Ich erhalte aber die Exception "Unable to find an entry point named 'GetValue' in DLL 'xyzdll.dll'.

Einen EntryPoint bei DllImport brauche ich ja nicht, da beide Funktionen (DLL und C#) gleich lauten.
Aber wie müsste es korrekt lauten?


//Bibliotheksfunktion in "xyzdll.dll"
XYZDLL_API    int GetValue( int *pValue );


    public partial class Form1 : Form
    {
        [DllImport("xyzdll.dll")]
        static extern int GetValue( out int pBrightness );
        
        private void button1_Click(object sender, EventArgs e)
        {
            int value = 0;
            GetValue(out value);
        }
    }

1.130 Beiträge seit 2007
vor 13 Jahren

1.) genaue fehlermeldung: entrypoint not found oder dll not found?
2.) betrachte die dll im dependency walker (depends.exe) und kopier den exakten namen (c++ dekoriert namen gerne)
3.) wenn name garnicht in der liste auftaucht: in deiner dll muss die funktion als __declspec(dllexport) gekennzeichnet sein
4.) du kannnst dir das ganze auch sparen, wenn du c++ interop machst (c++ für clr compilierst)

Projekte:Jade, HttpSaver
Zum Rechtschreiben gibts doch schon die Politiker. Aber die bauen auch nur mist!

C
Catwiesl Themenstarter:in
7 Beiträge seit 2010
vor 13 Jahren

Danke schon mal für die Hinweise.

zu 1.) entrypoint not found

zu 2.) dekorierter Name: ?GetValue@@YAHPAH@Z --> ist keine gültige Syntax
Undekoriert lautet der Name wie im ersten Posting: int GetValue( int *)
Es gibt noch eine C-Funktion: C_GetValue. Bei deren Aufruf kommt aber der Fehler "PInvokeStackImbalance was detected".

zu 4.) Die DLL ist von einem Drittanbieter. Aber ich komme vielleicht an den Code ran.

1.130 Beiträge seit 2007
vor 13 Jahren

ekorierter Name: ?GetValue@@YAHPAH@Z --> ist keine gültige Syntax

Damit hast du rausgefunden, dass folgendes nicht stimmt:

Einen EntryPoint bei DllImport brauche ich ja nicht, da beide Funktionen (DLL und C#) gleich lauten.

Damit wäre dein Problem sogut wie gelöst:


[DllImport("dllname.dll",EntryPoint="?GetValue@@YAHPAH@Z")]
....

Es gibt noch eine C-Funktion: C_GetValue. Bei deren Aufruf kommt aber der Fehler "PInvokeStackImbalance was detected".

Das kann vier mögliche Gründe haben:
a) Parameterzahl stimmt nicht überein
b) Callingconvention stimmt nicht überein. Diese lässt sich im dllimport-attribut explizit angeben. Da die funktion keine Dekoration hat, ist es höchstwahrscheinlich cdecl
c) Falsche typen bzw falsche Umwandlung (Marshaling)
d) Fehlerhafter c-code (Es ist schon eine Kunst derartige Fehler unabsichtlich so einzubauen, dass sie immer auftreten.)

Projekte:Jade, HttpSaver
Zum Rechtschreiben gibts doch schon die Politiker. Aber die bauen auch nur mist!

S
211 Beiträge seit 2010
vor 13 Jahren

Das Name-Mangling von C++ passt nicht mit dem von C# zusammen da die Funktion, wie du ja schon gesehen hast in C++ nicht einfach GetValue heißt sondern noch etwas hinzugefügt wird und das findet C# dann nicht.

Wenn du an den Code der DLL rankommst kannst du dort für die Funktion auch C-Linkage erzwingen, das sollte das Problem auch lösen:

extern "C" __declspec(dllexport) int GetValue( int *pValue );
1.130 Beiträge seit 2007
vor 13 Jahren

Nana im c#code einfach den entrypoint explizit anzugeben ist im konkreten fall sicherlich einfacher.

Ich habe aber auch schon von deinem extern "C"-trick gelesen. Allerdings hat er bei mir nicht wirklich funktioniert, als ich den probiert hatte. Hat zu haufenweise unerklärlicher fehler geführt.

Projekte:Jade, HttpSaver
Zum Rechtschreiben gibts doch schon die Politiker. Aber die bauen auch nur mist!

S
211 Beiträge seit 2010
vor 13 Jahren

Wenn ich die DLL selber schreibe, mach ichs grundsätzlich so, Fehler hat das bei mir noch nie produziert.

Bei DLLs von Drittanbietern geht es sicher nicht ganz so einfach, da ist dein Weg bestimmt der Bessere.