C++ DLL in Vb.net Projekt aufrufen (Übergabe "Doppel Pointer")

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 4 Antworten in diesem Thema. Der letzte Beitrag () ist von exc-jdbi.

    C++ DLL in Vb.net Projekt aufrufen (Übergabe "Doppel Pointer")

    Liebe VB Gemeinde,

    ich möchte mit VB.net (Visual Studio 2013) eine C++.dll (unmanaged) aufrufen. Dabei habe ich meiner Meinung nach ein Problem mit der Übergabe eines Parameters (Doppelpointer).
    Der unten beschrieben Programmcode dient mir als kleines "Testprojekt" zum verstehen und ausprobieren.

    -----
    Die Funktion wurde in C++ folgendermaßen definiert, bevor sie in eine .dll umgewandelt wurde:

    XXX_API double TestAdd(double ** a)
    {
    return *(a[0]) + *(a[1]);
    }

    -------

    Im C++ Header-file:
    XXX_API double TestAdd(double ** a);

    ------

    Ich habe ein C++ Beispielprojekt das funktioniert indem die DLL verwendet wird, der Aufruf sieht so aus:

    int main(void)
    {
    // zwei normale double Variablen anlegen und mit Werten belegen
    double a = 6;
    double b = 7;

    // Ein Array der Größe 2 von double Zeigern erzeugen
    double * vars[2];

    // jeweils die Adresse der double Variablen in das Array schreiben
    vars[0] = &a;
    vars[1] = &b;

    // Test Add aufrufen und den Wert ausgeben
    cout << a << " + " << b << " = " << TestAdd(vars) << endl;

    system("pause");
    }

    Ergebnis = 13
    ------

    Nun möchte ich die besagte DLL aus meinem VB.net Projekt aufrufen (Zielframework 4.5.2)

    Ich habe keine Idee wie der Aufruf, bzw. wie ich diesen "Doppelpointer" (double ** a) aus C++ in Vb.net übergeben/ übersetzen soll?

    Mein aktueller VB-Code:

    Imports System.Runtime.InteropServices

    <DllImport("C:\NameDerDLL.dll", CharSet:=CharSet.Auto, SetLastError:=True, _
    EntryPoint:="TestAdd", CallingConvention:=CallingConvention.Cdecl)> _
    Private Shared Function TestAdd(ByRef test()() As Double) As Double
    End Function

    Dim dblResult As Double
    dblResult = TestAdd(test)

    a dachte ich, ist ein Array von einem Array vom Typ Double und das entspräche ()() - passt aber nicht

    Fehlermeldung:
    Ein Ausnahmefehler des Typs "System.Runtime.InteropServices.MarshalDirectiveException" ist in VBDLLTestProject.exe aufgetreten.
    Zusätzliche Informationen: "parameter #1" kann nicht gemarshallt werden: Für geschachtelte Arrays ist keine Marshallunterstützung vorhanden..

    Unterstützt vb.net überhaupt Zeiger, bzw. kann das überhaupt so in VB.net umgesetzt werden?

    Vielen Dank schon mal Vorab!
    Grüße
    Moc

    Moc schrieb:

    umgesetzt werden
    Gugst Du hier.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Danke für die schnelle Hilfe. Trifft mein Thema zeimlich genau. Eine Frage zu Deiner Ausführung:

    " Die Kommunikation mit einer C++-DLL ist so aus .NET nicht möglich, da ein unmanaged C++-Objekt erstellt werden muss, und das ist aus .NET nicht möglich, dazu bedarf es eines Wrappers in Form einer C-DLL."

    C++DLL - VB - Bedeutet das tatsächlich gar keine Kommunikation ohne Wrapper möglich? Ich frage nur deshab, weil ich im Vorfeld mit einer vereinfachten C++DLL gestestet habe. Übergabe waren zwei Double die in der DLL addiert wurden und als Rückgabe das Ergebnis als Double lieferten. Das hat funktioniert aus VB raus. Als dann im zweiten Schritt allerdings dieser Doppel-Pointer als Übergabeparameter hinzukamen
    fehlte mir dazu jegliche Idee.

    Gruß
    Moc

    Moc schrieb:

    zwei Double
    sind zum Glück keine unmanaged Objekte.
    Natürlich kannst Du einzelne Funktionen aufrufen mit Parametern was auch immer.
    Wenn in der C++-DLL eine C++-Klasse instanziiert wird, mit der Du kommunizieren willst, brauchst Du einen Wrapper.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Guten morgen

    Hab soeben den Artikel gsehen.

    Da gibt es sicher Möglichkeiten. Hab mich zwar mit dem übergeben von Double-Array noch nicht beschäftigt. Aber sofern es da wirklich nichts gibt:

    Wie wäre es wenn du die Double-Array in eine Byte-Array oder Integer-Array umwandelst diese übergibst und diese dann in der Dll wieder zurückwandelst. Sollte meines erachtens kein Problem darstellen.

    Quellcode

    1. in VB.Net gibt es Marshal.UnsafeAddrOfPinnedArrayElement
    2. in C/C++ gibt es reinterpret_cast<Type*>


    Freundliche Grüsse

    exc-jdbi