VB DLL in BCB einbinden (XE 4)



  • Hallo zusammen,

    ich habe eine VB - dll (VB 2010 Express) und will diese in ein BCB-Projekt einbinden.

    VB- Code :

    Public Class MainClass
        Public Function Wandle(ByVal Path As String) As Integer
        '...
        '...
        End Function
    End Class
    

    Diese Funktion würde ich gerne laden. Wenn ich das jedoch mittels

    this->A=LoadLibrary(VBDLLADR_w);
    if(A!=NULL)
    {
    Wandle=(TWandle*)GetProcAddress(A,"_Wandle");
    return true;
    }
    else
    {
    else return false;
    }
    

    wobei TWandle wie folgt definiert ist

    typedef int TWandle(String Path);
    

    gibt es beim Laden auch keine Probleme. Jedoch beim ersten Aufruf der Funktion Wandle bekomme ich eine Fehlermeldung

    acess violation at 0x00000000:read of address 0x00000000

    ich schließe daraus, dass er also keine Adresse für die Funktion laden kann. Hat jemand eine Idee woran das liegt?



  • Bist Du sicher, daß die Funktion als _Wandle exportiert wird?
    Schau Dir die DLL mal mit dem DependencyWalker an, hier kannst Du sehen wie der Name der exportierten Funktion lautet.

    Allerdings wird dich dies vermutlich nicht viel weiterbringen.
    In deinem typedef verwendest Du einen String als "Funktionsparameter". Dies ist mit Sicherheit eine andere Implementierung als der String in VB, d.h. das kann nicht funktionieren.

    DLL Funktionsparameter sollten immer PODs (in diesem Fall ein char*) sein.
    Das einfachste wäre in der VB DLL ein Wrapperfunktion zu bauen welche als Parameter char* verwendet.
    Habe leider kein Plan von VB deshalb weiß ich nicht wie der Datentyp dort heißt.

    MfG Stephan



  • Visual Basic 2010 ist eine .NET-Programmiersprache. Einfach so einen DLL-Export zu machen ist da nicht wie in C++, da muß man sich auch über den Übergang zwischen Native Code und Managed Code Gedanken machen. Außerdem stimmt das bei dir konzeptuell nicht; dein "Wandle" ist eine Methode einer Klasse und braucht also als Argument auch eine Klasseninstanz. Und die String-Typen von C++Builder und .NET sind natürlich nicht kompatibel.

    Mögliche Lösungen sind:
    - eine C++/CLI-Assembly, die einen nativen DLL-Export bereitstellt und den .NET-Code aufruft
    - Hosting der CLR in deiner Anwendung
    - Einbinden der DLL via COM Interop; dafür mußt du dich mit COM in C++ beschäftigen
    - DllExport für .NET

    Ich weiß nun natürlich nicht, wie komplex die Interaktion noch werden soll. Persönlich würde ich COM Interop bevorzugen, obwohl das für einen einzelnen Export vielleicht Overkill ist. C++/CLI ist in der Theorie einfach und praktisch, ist in der Praxis aber oft zum Haareraufen (wehe, wenn du statisch initialisierte Objekte in deiner C++/CLI-Assembly hast!). Und explizites CLR-Hosting ist sowieso nur was für Masochisten 🙂



  • Danke erstmal. Was das passende Pendant zu char* in VB ist bekomme ich raus. Mit dem Thema COM habe ich mich noch nicht besoinders beschäftigt, aber ist das Linken mittels LoadLibrary() nicht schon COM-Technologie - oder anders : Weiß jemand wie maN eine VB DLL mittels COM einbindet?



  • Sebastel schrieb:

    aber ist das Linken mittels LoadLibrary() nicht schon COM-Technologie

    Nein. Bitte lies die Begriffe auf Wikipedia oder so nach.

    Sebastel schrieb:

    oder anders : Weiß jemand wie maN eine VB DLL mittels COM einbindet?

    Du mußt deine Assembly und deine Klasse "COM Visible" machen. Wie das geht, wissen die hier:
    http://msdn.microsoft.com/de-de/library/6bw51z5z.aspx

    Damit bekommst du eine Typbibliothek für deine Assembly. Und wie du die in C++Builder importierst, steht hier:
    http://docwiki.embarcadero.com/RADStudio/en/Importing_Type_Library_Information


Log in to reply