C++ DLL in C# verwenden - Stack-Fehler bei Parameter

Gast #2097553
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
Gast #2097581
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.
Gast #2097586
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)
Gast #2097597
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
Gast #2097616
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
#2097617
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
#4009902
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

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 15 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.