Forum: PC-Programmierung C++ DLL in C# verwenden - Stack-Fehler bei Parameter


von Sam (Gast)


Lesenswert?

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

von Peter (Gast)


Lesenswert?

definiere sie mal stdcall.

von Sam (Gast)


Lesenswert?

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.

von Peter (Gast)


Lesenswert?

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)

von Sam (Gast)


Lesenswert?

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

von Peter (Gast)


Lesenswert?

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

von Markus V. (valvestino)


Lesenswert?

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

von GSc_Dev (Gast)


Lesenswert?

Hallo,

vielen Dank für diesen Thread!
Der Hinweis, __stdcall zu ergänzen, hat mir (nach 3 Jahren :-) sehr 
geholfen!
Grüße,
Günter

von Gerald T. (geraldtrost)


Lesenswert?

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

von bluppdidupp (Gast)


Lesenswert?

Wie sieht denn die Einbindung aus?
Die Variante von hier funktioniert eigentlich:
http://www.pinvoke.net/default.aspx/user32.showwindow

von Gerald T. (geraldtrost)


Lesenswert?

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
Noch kein Account? Hier anmelden.