Aufrufen einer .dll- Übergabe eines doppelten Pointers

  • VB.NET

Es gibt 7 Antworten in diesem Thema. Der letzte Beitrag () ist von alexanderdg.

    Aufrufen einer .dll- Übergabe eines doppelten Pointers

    Liebe VB Gemeinde,

    ich möchte mit VB (Visual Studio 2010) eine .dll aufrufen. Dabei habe ich meiner Meinung nach ein Problem mit der Übergabe der parameter. Die Funktion wurde in C folgendermaßen definiert, bevor sie in eine .dll umgewandelt wurde:

    Quellcode

    1. int wmlfLevel1(double* input2D, int size, char* message, double** output2d)


    Mit VB wollte ich nun diese .dll folgendermaßen aufrufen:

    Quellcode

    1. Imports System.Runtime.InteropServices
    2. Module Module1
    3. Public test_data(0 To 2, 0 To 2) As Double
    4. Public test_size As Integer
    5. Public mess As String
    6. Public test_output_2d As Double
    7. Public stat_int As Integer
    8. 'Declare Function wh_fun Lib "level2.dll" Alias "_wmlfLevel1" (ByVal data(,) As Double, ByVal size As Integer, ByVal message As String, ByRef output2d() As Double) As Integer
    9. <DllImport("level2.dll")> Function _wmlfLevel1(ByVal input2D(,) As Double, ByVal size As Integer, ByVal message As String, ByRef output As Double) As Integer
    10. End Function
    11. Sub Main()
    12. test_data(0, 0) = 1
    13. test_data(0, 1) = 2
    14. test_data(0, 2) = 3
    15. test_data(1, 0) = 4
    16. test_data(1, 1) = 5
    17. test_data(1, 2) = 6
    18. test_data(2, 0) = 7
    19. test_data(2, 1) = 8
    20. test_data(2, 2) = 9
    21. test_size = 3
    22. mess = "Test"
    23. stat_int = _wmlfLevel1(test_data, test_size, mess, test_output_2d)
    24. End Sub
    25. End Module


    Ich habe schon probiert die ByVal und die Byref Ausdrücke auszutauschen, so wie sie jetzt gesetzt sind dürfte es passen (die .dll zeigt die Eingangsdaten in einem externen Fenster korrekt an). Ich bekomme jedoch immer den Fehler PInvokeStackImbalance.. Ich vermute es liegt an der Übergabe an den pointer double** output2d.

    Kann mir irgendwer helfen und sagen, wie ich die .dll richtig anspreche??


    Vielen Dank und schöne Grüße,

    Alexander
    Es kommt immer die Fehlermeldung PInvokeStackImbalance

    Die Eingabedaten lasse ich mir mit der .dll in einem Fenster anzeigen. Danach sollte es zu einer einfachen Berechnung kommen und das Ergebnis sollte an das vb zurückgegeben werden. Anscheinend kommt es bei der Rückgabe zum Fehler.

    VB.NET-Quellcode

    1. <DllImport("dieAssembly.dll")> _
    2. Public Shared Function wmlfLevel1(input2D() As Double, size As Integer, message() As Char, output2D()() As double)As Integer
    3. End Function


    Edit: double* ist ein Array vom Typ Double = () As Double, ich bin mir nicht sicher, ob die Assembly mit einem String zurechtkommt...output2D ist ein Array von einem Array vom Typ Double und das entspricht ()() und wäre nicht dasselbe wie (,), da dies ein zweidimensionaler Array wäre...
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    Vielen Dank für Eure Hilfe- ich habe nicht gedacht, dass mir so schnell geantwortet wird (echt toll!!). Ich hab nämlich um 4 einen Termin und werd mir das ganze morgen nochmals in Ruhe anschauen.

    Vielen Dank nochmals und schönen Nachmittag,

    Alexander

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „alexanderdg“ ()

    Hallo nochmals,

    ich habe da noch eine weiterführende Frage. Heute habe ich die Parameterübergabe probiert und den folgenden Code eingegeben


    Quellcode

    1. Public Function wmlfLevel1(ByVal ByValinput2D(,) As Double, ByVal size As Integer, ByVal message() As Char, ByRef output2D()() As Double) As Integer
    2. End Function


    Nun bekomm ich die Fehlermeldung: MarshalDirectiveException: "parameter #4" kann nicht gemarshallt werden: Für geschachtelte Arrays ist keine Marshallunterstützung vorhanden..

    Ich habe mir auch schon die Hilfe auf der msdn.microsoft Homepage angeschaut- aber da versteh ich leider nur Bahnhof... Vielleicht kennt sich jemand von Euch damit aus?

    Vielen Dank und schöne Grüße,

    Alexander


    P.S:
    (Die ByVal/ByRaf Statments habe ich nicht löschen könnnen, was aber meiner Meinung nach nicht der Kern des Problems ist)
    hmm, dann wird der vierte Parameter wohl doch ein 2Dimensionaler Array sein, welcher auch gemarshallt werden können sollte^^
    also output2D(,) As Double
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    Jetzt hab ich es mit output2D(,) probiert und das liefert mir wieder den anfänglichen Fehler PInvokeStackImbalance (zumindest wird die .dll aufgerufen, was ich daran sehe, dass sich ein Ausgabefenster öffnet und die Eingabedaten angezeigt werden). Bei dem Übergabe des Ergebnisarrays output2D haperts aber.

    Bin etwas ratlos und fürchte, dass das Ding nicht so leicht zu knacken ist!?

    Übrigens das gleiche hab ich (mit Hilfe von außen) auch mit C++ probiert und dort funktioniert der Aufruf- blöderweise brach ich das Ding aber in vb. Wenn es interessiern sollte- so würde das ganze in C++ aussehen:

    Quellcode

    1. #include"stdafx.h"
    2. /* Function handle to the wrapper functions in the wrapper DLL (level2.c) */
    3. typedef int ( *h_w_mlfun) (double* data, int size, char *message, double** output2d);
    4. typedef int ( *h_w_mlterm)(void);
    5. int main(void) {
    6. double data[][3]={ {1, 2, 3}, {6, 6, 6}, {3, 2, 1}};
    7. int i, j;
    8. char *message="String from level3.c";
    9. double *output2d=NULL;
    10. int resultofMfun=FALSE;
    11. int retval = EXIT_FAILURE;
    12. /* Handles to wrapper M functions */
    13. h_w_mlfun wh_fun;
    14. //FARPROC wh_fun;
    15. h_w_mlterm wh_term;
    16. HINSTANCE hdll;
    17. char char_string[100] = "level2.dll";
    18. LPCWSTR lpcwstr_string = A2BSTR(char_string);
    19. /* Expect level2.dll on system path or the same directory as this executable */
    20. //hdll= LoadLibrary(char_string);
    21. hdll= LoadLibrary(lpcwstr_string);
    22. if(hdll==NULL){
    23. printf("Unable to load level2.dll\n");
    24. }
    25. else {
    26. /* Obtain the address of the required wrapper function in the loaded DLL and cast it */
    27. wh_fun=(h_w_mlfun)GetProcAddress(hdll, "_wmlfLevel1");
    28. /* Call this function with the expected input arguments */
    29. resultofMfun=(wh_fun)(*data, 3, message, &output2d);
    30. if(resultofMfun){
    31. printf("Result:\n");
    32. for(i=0;i<3;++i){
    33. for(j=0;j<3;++j)
    34. printf("\t%lf", *(output2d+i*3+j));
    35. printf("\n");
    36. }
    37. retval = EXIT_SUCCESS;
    38. }
    39. else{
    40. printf("Unable to call wrapper function\n");
    41. }
    42. wh_term=(h_w_mlterm)GetProcAddress(hdll, "_terminateMCR");
    43. (wh_term)();
    44. system("PAUSE");
    45. }
    46. return retval;
    47. }