Hallo, ich habe eine DLL in C++ erstellt (Visual Studio) und sie funktioniert auch unter C++. Das Problem zeigt sich erst, wenn ich diese in C# einbinden will. Alle Funktionen ohne Parameter gehen ohne Fehler. Bei Funktionen mit Parameter bekomme ich immer ein Stack Problem. Auch wenn ich nur eine einfache Byte-Variable übergebe. Ich glaube es liegt an meiner DLL und nicht am verwendeten Aufruf. Z.B. habe ich die Funktion BOOL MessageBeep(UINT) erfolgreich in C# einbinden können. Aber meine eigene Funktion BOOL Irgendwas(UINT) macht trotzdem den Stack Fehler. Ich bin etwas ratlos und hoffe auf Hilfe! Gruß Sam
Ich bin nicht sicher, ob ich Dich richtig verstanden habe. Im Moment sind die Funktionen mit
1 | extern "C" __declspec(dllimport) |
definiert. Stattdessen einfach
1 | __stdcall |
? Hab ich ausprobiert - es hilft leider nicht! Das hier ist die Fehlermeldung:
1 | Ein Aufruf an die PInvoke-Funktion hat das Gleichgewicht des Stapels |
2 | gestört. Wahrscheinlich stimmt die verwaltete PInvoke-Signatur nicht mit |
3 | der nicht verwalteten Zielsignatur überein. Überprüfen Sie, ob die |
4 | Aufrufkonvention und die Parameter der PInvoke-Signatur mit der nicht |
5 | verwalteten Zielsignatur übereinstimmen. |
Wie hast du es in C# definiert? Ich hatte es immer ohne __declspec(dllimport) dafür aber mit .def Datei gemacht. Dort hatte ich dann irgendwo __stdcall hingeschrieben und dann ging es. (Bei mir kam aber keine Fehlermeldung sonder das Programm ist nur abgestützt)
Hallo Peter, erstmal vielen Dank für Deine Hilfe. Es funktioniert! Ich hatte meine DLL-Funktionen bisher in etwa so definiert:
1 | extern "C" __declspec(dllimport) BOOL Machwas(UINT u); |
wenn ich nun Deinen _stdcall einbaue (an der richtigen Stelle^^), dann klappts!
1 | extern "C" __declspec(dllimport) BOOL __stdcall Machwas(UINT u); |
Jetzt frag ich mich nur, warum? Was macht das __stdcall? Wer mir das kurz erklären will, darf das gerne tun! Ansonsten werd ich das mal googeln. Gruß Sam
es legt fest wie die parameter auf den Stack gelegt werden. Bei Pascal ist der aufrufer für das aufräumen des Stack verantwortlich. Bei C macht es die funktion. Auch die Reihenfolge muss festgelegt werden und dafür gibt ebend verschiendene standards - einer davon ist halt stdcall
Es gibt mehrere Möglichkeiten, wie Parameter über den Stack übergeben werden, wer die Daten auf den Stack legt und wer sie wieder entfernt. Dies definiert man über z.B. __stdcall (MS-VC). Bei MS gibt es da auch noch andere Calling Conventions (__cdelc, __clrcall, ...). Der Trick ist: die Calling-Convention muss bei Aufrufer und beim Aufgerufenen zusammenpassen. Eine weitere Möglichkeit, deine Software zum Laufen zu bekommen wäre, Du gibst in C# beim DllImport die passende Aufruf-Konvention an. Weiterführende Doku: siehe MSDN Gruß Markus
Hallo, vielen Dank für diesen Thread! Der Hinweis, __stdcall zu ergänzen, hat mir (nach 3 Jahren :-) sehr geholfen! Grüße, Günter
Noch ein Hinweis: Ich hatte in C# die Funktion ShowWindow() aus user32.dll eingebunden. Alles ging problemlos bis ich die ZielPlattform auf ".NET 4.0" geändert habe, dann kam die Stack-Fehlermeldung! Ich kompiliere jetzt für .NET 3.5 bis ich eine Lösung gefunden habe. Gerald
Wie sieht denn die Einbindung aus? Die Variante von hier funktioniert eigentlich: http://www.pinvoke.net/default.aspx/user32.showwindow
Interessant! Wenn man das enum ShowWindowCommands in der Deklaration benützt dann funkt es auch unter DotNET 4.0 ! vielen Dank Gerald
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.