C-DLL nach .NET wrappen
-
Hallo,
vielleicht kann mir jemand helfen. Ich möchte gerne eine C-DLL in C# verwenden. Ich weiß, dass ist ein C++ Forum, aber vielleicht weiß es ja gerade hier ein "alter Hase".
Im Header steht:
# ifdef WIN32
# ifdef SIE_DECLARE_STATIC
# define SIE_DECLARE(type) SIE_EXTERN_C type __cdecl
# else
# define SIE_DECLARE(type) SIE_EXTERN_C __declspec(dllimport) type __cdecl
# endif
# else
# define SIE_DECLARE(type) SIE_EXTERN_C type
# endif...
typedef void sie_File;
typedef void sie_Context;...
SIE_DECLARE(sie_Context sie_context_new(void);
SIE_DECLARE(sie_File sie_file_open(void *context_object, const char *name);WEnn ich es richtig verstehe, geben beide Funktionen einen Pointer auf void zurück. Die zweite Funktion übernimmt einen Pointer auf void als ersten Parameter und einen Pointer auf const char* als zweiten Parameter.
So habe ich es in C# eingebunden:
[DllImport("libsie.dll")]
public static extern IntPtr sie_context_new();[DllImport("libsie.dll")]
public static extern IntPtr sie_file_open(IntPtr context, System.String filename);Die Funktion sie_context_new() kann ich aufrufen, der IntPtr hat auch einen Wert größer 0. Beim Aufruf von sie_file_open() kommt es zu folgendem Fehler:
PInvokeStackImbalance wurde erkannt.
Ein Aufruf an die PInvoke-Funktion "LibsieCSharp!LibsieCSharp.LibsieWrapper::sie_file_open" 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.
Ich vermute, dass es an dem const char* liegt. Weiß jemand wie man die sie_file_new() wrappt? Danke!
-
Das ist konkret das C++/CLI Forum (nicht C++ wie Du vermutet hast) - C++/CLI ist natürlich eine Lösung, jedoch hast Du ja eine DLL mit C Interface, was eher für P/Invoke sprechen würde (wie von Dir schon ansatzweise gezeigt).
Konkret zu deinem Problem:
Wie schon die Fehlermeldung sagt, solltest Du mal die Aufrufkonvention (Calling Convention) überprüfen, bzw. explizit angeben. Siehe als Bsp. mal hier.
-
Jawohl, so geht es:
[DllImport("libsie.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr sie_file_open(IntPtr context, System.String filename);Danke!!!