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!!!


Log in to reply