Forum: PC-Programmierung [C#] C-DLL-Funktion führt zum Fehler (PInvokeStackImbalance wurde erkannt.)


von Marco S. (masterof)


Lesenswert?

Hi,

Ich versuche gerade eine selbst geschriebene C-DLL in mein C#-Projekt zu 
verwenden. Wenn ich die Funktion aus der DLL aufrufe und der Debugger 
kommt wieder aus der DLL-Funktion heraus, dann stoppt der Debugger mit 
der Fehlermeldung:

"PInvokeStackImbalance wurde erkannt.

Ein Aufruf an die PInvoke-Funktion 
"ObjekterkennungCam!ObjekterkennungCam.Form1::SobelFilter" hat das 
Gleichgewicht des Stapels gestört. Wahrscheinlich stimmt die verwaltete 
PInvoke-Signatur nicht mit der nicht verwalteten Zielsignatur überein. 
Überprüfen Sie, ob die Aufrufkonvention und die Parameter der 
PInvoke-Signatur mit der nicht verwalteten Zielsignatur übereinstimmen."

Als Entwicklungsumgebeung nutze ich Visual Studio 2010 Express mit dem 
.NET 4.0-Framwork.

Was habe ich falsch gemacht oder gibt es einen anderen weg die Funktion 
aus der C-DLL aufzurufen?

Gruß Marco


Form1.cs
1
....
2
[DllImport("funktion.dll")]
3
        unsafe static extern void SobelFilter(int hoehe, int breite);
4
5
....
6
int hoehe = 4;
7
int breite = 5;
8
SobelFilter(breite, hoehe);
9
Application.DoEvents(); //Hier kommt die Fehlermeldung. Egal was ich hier mache
10
....

dllmain.c
1
/* Replace "dll.h" with the name of your header */
2
#include "dll.h"
3
#include <windows.h>
4
#include <stdio.h>
5
#include <stdlib.h>
6
7
DLLIMPORT void Filter (int hoehe, int breite)
8
{
9
    int wert = hoehe * breite;
10
}
11
12
13
BOOL APIENTRY DllMain (HINSTANCE hInst     /* Library instance handle. */ ,
14
                       DWORD reason        /* Reason this function is being called. */ ,
15
                       LPVOID reserved     /* Not used. */ )
16
{
17
    switch (reason)
18
    {
19
      case DLL_PROCESS_ATTACH:
20
        break;
21
22
      case DLL_PROCESS_DETACH:
23
        break;
24
25
      case DLL_THREAD_ATTACH:
26
        break;
27
28
      case DLL_THREAD_DETACH:
29
        break;
30
    }
31
32
    /* Returns TRUE on success, FALSE on failure */
33
    return TRUE;
34
}

dllmain.h
1
#ifndef _DLL_H_
2
#define _DLL_H_
3
4
#if BUILDING_DLL
5
# define DLLIMPORT __declspec (dllexport)
6
#else /* Not BUILDING_DLL */
7
# define DLLIMPORT __declspec (dllimport)
8
#endif /* Not BUILDING_DLL */
9
10
11
DLLIMPORT void Filter (int hoehe, int breite);
12
13
#endif /* _DLL_H_ */

von Warum_denn (Gast)


Lesenswert?

ähm... "SobelFilter" ist aber nicht in der DLL enthalten, sondern nur 
"Filter"... ??

von Peter II (Gast)


Lesenswert?

irgendwie stimmt doch etwas mit dem Namen nicht. Ist das wirklich der 
passende code dazu?

in der dll hast du "Filter" exportiert, in C# verwendest du 
"SobelFilter" - woher soll denn c# wissen das er die filter funktion 
aufrufen soll?

von Marco S. (masterof)


Lesenswert?

Mist da ist ein Fehler beim Kopieren entstanden :(
Die verwendete Funktion heißt SobelFilter und ist auch richtig in der 
DLL eingetrag.

Gruß Marco

von Peter II (Gast)


Lesenswert?

Marco S. schrieb:
> Die verwendete Funktion heißt SobelFilter und ist auch richtig in der
> DLL eingetrag.

sicher? dann zeigt bitte noch einmal den echten code - ohne änderung.

von Marco S. (masterof)


Angehängte Dateien:

Lesenswert?

Hi Peter II,

Ich habe die beiden Dateien als ZIP-Datei angehängt.

Gruß Marco

von Warum_denn (Gast)


Lesenswert?

wie compilierst du die dll? als 64bit oder 32 bit?

von Marco S. (masterof)


Lesenswert?

Hi Warum_denn,

Als 32Bit-Version kompaliere ich die DLL.

Habe oben vergessen noch zu erwähnen das der Compiler für die DLL der 
Dev-C++ Version 4.9.9.2 ist.

Gruß Marco

von Peter II (Gast)


Lesenswert?

kannst du die dll mal hochladen?

von Marco S. (masterof)


Angehängte Dateien:

Lesenswert?

Hi,

Hier ist die DLL.

Gruß Marco

von Warum_denn (Gast)


Lesenswert?

ich denke, es liegt an den aufruf-konventionen....

wie wird die dll-funktion denn exportiert? als stdcall oder als cdecl? 
und wie wird sie in c# importiert?


versuche mal in c# die funktion so einzubiden:
1
[DllImport("funktion.dll", CallingConvention=CallingConvention.Cdecl)]
2
        unsafe static extern void SobelFilter(int hoehe, int breite);

http://de.wikipedia.org/wiki/Aufrufkonvention

von Markus V. (valvestino)


Lesenswert?

Die Exception besagt, dass entweder die Aufrufparamter inkonsistent sind 
(Größe der Daten auf dem Stack) oder dass die CallingConvention nicht 
übereinstimmt.

So wie ich das sehe, ist Deine DLL mit der CallingConvention __cdecl 
compiliert (der Default). Die Default CallingConvention von .Net PInvoke 
ist aber WinApi (was StdCall bzw. __stdcall entspricht).

Versuche mal folgendes:
1
[DllImport("funktion.dll",CallingConvention = CallingConvention.Cdecl)]

Gruß
Markus

von Warum_denn (Gast)


Lesenswert?

@markus:

hehe, ich bin schneller ;)

von Marco S. (masterof)


Lesenswert?

Hi,

Ihr habt beide Recht :)

Danke und noch einen schönen Abend.

Gruß Marco

von Markus V. (valvestino)


Lesenswert?

Warum_denn schrieb:
> hehe, ich bin schneller ;)

Du hast schneller gepostet, bist aber seit mindestenss einer 3/4-Stunde 
damit befasst, ich erst 5 Minuten! Wer ist schneller? :-D ;-)

Gruß
Markus

von Peter II (Gast)


Lesenswert?

mist jetzt bin ich 3.

die Parameter werden nicht auf dem Stack übergeben, wie es die dll 
erwartet.

von Markus V. (valvestino)


Lesenswert?

Peter II schrieb:
> mist jetzt bin ich 3.

Shit happens ;-)

Gruß
Markus

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

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.