DllImport und Pfadangabe

  • VB.NET

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    DllImport und Pfadangabe

    Hallole,

    ich muss eine native DLL in mein VB.NET Projekt einbinden und habe nun das Problem, dass DllImport nur konstante Pfadangaben haben möchte (Konstanter Ausdruck erforderlich).

    Es gibt aber verschiedene Szenarien und der Pfad müsste dynamisch zur Laufzeit ermittelt werden. Wie kriege ich die Pfadangabe aus einer Variablen an DllImport übergeben?


    VB.NET-Quellcode

    1. <DllImport(System.IO.Path.Combine({Environment.CurrentDirectory, DLLName}), SetLastError:=True, CharSet:=CharSet.Ansi)>
    2. Public Function _initDLL() As Boolean
    3. End Function


    Oder Alternativ wäre es möglich, die alten Dinos LoadLibrary etc. aus kernel32 einzubinden und die DLL dann damit reinzuladen. Ich finde nur keine Hinweise, was ich mit dem IntPtr anfangen soll, den mir dann getProcAdress liefert. Irgendwie muss ich einen Delegaten definieren. Aber mir erschließt sich nicht, wie ich aus dem IntPtr einen Funktionsaufruf bastele.

    Hinweise werden freudig aufgenommen.

    Gruß

    MQ
    hmm, den Attribute-Hack.

    Sry, verstehe nur Bahnhof.

    Auf die Schnelle habe ich nur gefunden, wie man die Attribute aus einer Klasse ausliest. DllImport ist aber keine Klasse und darf auch nicht in einer Instanzmethode erscheinen. Sobald ich versuche, DllImport in einer Klasse zu schachteln, kommt eine entsprechende Fehlermeldung.
    Hallo @MasterQ

    Sowas habe ich auch schon mit UnmanagedFunctionPointer realisiert. Ist aber schon ein Weilchen her.
    docs.microsoft.com/de-de/dotne…rvices_CallingConvention_

    Spoiler anzeigen

    VB.NET-Quellcode

    1. <DllImport("kernel32.dll")> _
    2. Public Shared Function LoadLibrary(ByVal dllName As String) As IntPtr
    3. End Function
    4. <DllImport("kernel32.dll")> _
    5. Public Shared Function GetProcAddress(ByVal hModule As IntPtr, ByVal methodeName As String) As IntPtr
    6. End Function
    7. <DllImport("kernel32.dll")> _
    8. Public Shared Function FreeLibrary(ByVal hModule As IntPtr) As Boolean
    9. End Function


    Leider habe ich kein entsprechendes Beispiel gerade präsent. Aber auf Github gibt es bestimmt ein Beispiel.
    docs.microsoft.com/de-ch/archi…-unmanaged-dll-from-net-c

    Die Idee von EDR finde ich jetzt auch noch interessant. Könnte mir vorstellen, dass das sogar funktioniert. Müsste man ausprobieren.

    Freundliche Grüsse

    exc-jdbi
    @MasterQ Welche Pfade können denn vorkommen?
    =====
    Einmal kannst Du mit Assembly.Load() arbeiten docs.microsoft.com/de-de/dotne…oad?view=netframework-4.8
    zum anderen mit DirectoryCatalog() docs.microsoft.com/de-de/dotne…log?view=netframework-4.8
    Hab ich beides implementiert.
    Ersteres ist recht simpel und allgemein, bei letzterem müssen die DLLs mit [Export(typeof(I_DEIN_INTERFACE))] compiliert werden.
    =====
    Verfügst Du über die Quellen der DLLs?

    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!

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

    z.B. die User-Verzeichnisse bzw. C:\Users\<Username>\AppData\...

    Immer mehr Anwendungen setzen sich nicht in die klassischen Verzeichnisse wie C:\Programme sondern irgendwo ins Roaming-Verzeichnis, vermutlich um die Sache mit den Admin-Rechten zu umgehen. Keine Ahnung warum sonst.
    @MasterQ

    RodFromGermany schrieb:

    Verfügst Du über die Quellen der DLLs?
    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!
    Ich kenne den Entwickler, konnte aber bisher nicht zu ihm durchdringen.

    Aber das hat sich jetzt geändert. Hatte grad mit ihm telefoniert und er bastelt mir was in C# zusammen. Bin mal gespannt.

    Somit scheint diese Kuh von Eis.

    Trotzdem würde mich interessieren, ob man dieses Hindernis prinzipiell umgehen kann, nämlich eine Variable nachträglich in eine Konstante umzuwandeln.

    VB.NET-Quellcode

    1. Dim a As Integer = 4
    2. Const b As Integer = a.toConst


    oder sowas in der Art.


    Gruß

    MQ

    MasterQ schrieb:

    eine Variable nachträglich in eine Konstante umzuwandeln.
    Kannst Du das mal motivieren?
    Wenn der Quellcode da ist, schreib doch einfach Const hin.
    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!
    der Quellcode ist (zumindest jetzt) nicht vorhanden. Das User-verzeichnis kann nur zur Laufzeit ermittelt werden und ist daher nicht für alle Anwendungsfälle konstant aber eben für die aktuelle Instanz. Das Verzeichnis in dem die DLL liegt wird sich im Laufe der Ausführung des Programmes nicht ändern, ist in diesem Sinne schon konstant, ist aber zur Compile-Zeit nicht bekannt.

    In meinem Fall wäre es sicher sinnvoller, wenn DllImport als Dateinamen auch Variable akzeptieren würde, das ist aber wahrscheinlich aus technischen Gründen nicht machbar. Ansonsten wüsste ich nicht, warum das auf Konstanten sonst limitiert wäre.

    Dass eine Konstante was grundsätzlich anderes ist als eine Variable weiß ich natürlich. Hätte ja sein können, dass es da einen Kniff gibt, den ich nicht kenne. Unwahrscheinlich aber es hätte ja sein können.

    Gruß

    MQ

    MasterQ schrieb:

    der Quellcode ist (zumindest jetzt) nicht vorhanden
    Du kannst also in den Projekten keine Änderungen vornehmen, damit fällt DirectoryCatalog() aus, sofern die DLL nicht so compiliert ist.
    Da musst Du Dich mit Assembly.Load() befassen.
    Ich gehe mal davon aus, dass die zu instanziierende Klasse (mindestens) ein bekanntes Interface implementiert.
    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!