DLL einbinden

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

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

    DLL einbinden

    Guten Abend,

    ich versuche nun seid ein paar Stunden herauszubekommen, wie ich eine DLL in mein Projekt einbinden kann.
    Wenn ich das über "Verweise" in den Projekt Settings versuche,
    bekomme ich folgende Meldung: siehe Dateianhang

    Die folgende Info steht in eine readme Datei:

    siosifm.dll is made with the free MinGW-GNU compiler.
    Unfortunately Microsoft removes the tool to import DLLs from other
    compilers with VisualStudio 32-bit. We provide an import lib without
    any support as it is. The recent import lib is based on DL version 1.4.0
    Newer functions may not be contained.

    The Knowlagdebase article
    support.microsoft.com/kb/131313/en-us
    describes how to make import libs by yourself.
    In summary the following steps are necessary:

    * Launch : DUMPBIN /EXPORTS siosifm.DLL siosifm.txt
    * Create a siosifm.def file (text editor) and copy the function names
    from the "name"-column of the siosifm.txt (created in the last step) into
    the exports-section
    A sample of the siosifm.def file may look like:

    LIBRARY SIOSIFM
    EXPORTS
    IfmInit @1
    IfmOpenUSB @2
    IfmCloseDevice @3
    IfmClose @4

    The ordinal numbers (@...) are optional.
    * Launch: LIB /DEF:siosifm.def
    creates the required siosifm.lib

    Leider werde ich daraus nicht schlau.
    Auf der Hersteller Seite steht, das man die DLL in verschiedenen Sprachen verwenden kann.
    Aber wie? Was muss ich tun?

    Es gibt auch noch fertige C++ Projekte, wo in der sich auch noch eine dll befindet.

    mfg.

    Kiter20
    Bilder
    • dll.JPG

      33,61 kB, 452×315, 123 mal angesehen
    "Mann" lernt mit seinen Projekten.
    Da hast du eine native DLL, ist ohne Net-Framework erstellt worden. Benutzen kannst du sie doch, via DllImport/Pinvoke. Dazu musst du die Doku studieren und fleissig die Funktionen runterschreiben.

    Hast du einen Link zur Doku und kannst den mal posten? Google gibt mir nur 2 Ergebnisse, wenn ich nach SIOSIFM.dll suche. Der 1. ist nicht interessant, beim 2. warnt mein browser mich.(Diese Seite könnte schädliche Programme enthalten)

    Du kannst auch in der Header-Datei schauen welche Funktionen drin stecken. EIn Beispiel einer anderen Dll
    Aus der .h

    C-Quellcode

    1. BOOL BASSDEF(BASS_ChannelPlay)(DWORD handle, BOOL restart);

    So dann in .net, wobei die dll im selben Ordner wie die exe ist, wobei man of den marshal bemühen muss.

    VB.NET-Quellcode

    1. <DllImport("bass.dll")>
    2. Public Shared Function BASS_ChannelPlay(handle As Integer, restart As Boolean) As Boolean
    3. End Function




    Vllt. hilft dir das auch weiter:
    Austausch von Daten zwischen einer VB.NET-exe und einer C-DLL, 32 und 64 Bit
    Cloud Computer? Nein Danke! Das ist nur ein weiterer Schritt zur totalen Überwachung.
    „Wer die Freiheit aufgibt, um Sicherheit zu gewinnen, wird am Ende beides verlieren.“
    Benjamin Franklin

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „NoIde“ ()

    @NoIde So isses.
    @kiter20 Achte darauf, dass Du mit x86 oder x64 compilierst, native DLLs können nicht AnyCPU!
    Pack die DLL in ein separates Verzeichnis Deines Projekts und kopiere sie im PostBuild-Step neben die Exe.
    Mach Dir am besten eine Wrapper-Klasse, die das PInvoke-Zeugs handelt.
    Wenn Du diese DLL öfter brauchst, überlege, ob Du den Wrapper in eine separate DLL packst.
    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!
    @Nolde ein böse Seite kann ich ausschließen. Der Hersteller ist mir bekannt.
    Sios stellt Lasermesssysteme her.
    Wir haben in unserem Unternehmen uns jetzt so etwas angeschafft. Er bietet auch eigene Software an. Aber nun halt auch die Möglichkeit selber etwas zu programmieren.

    Es gibt auch einen Ordner "VisualStudio" aus dem stammt der Text der readme.
    In diesem Ordner sind 2 andere Dateien.
    siosifm.lib
    siosifm.def

    Kann man damit eher was anfangen?
    "Mann" lernt mit seinen Projekten.

    kiter20 schrieb:

    Kann man damit eher was anfangen?
    Wenn Du einen Wrapper in Managed C++ (CLI) schreiben willst, kannst Du die Lib dazu linken und bekommst eine Assembly mit nativem Part in einer Datei.
    Meine Empfehlung: Lass das jedoch sein.
    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!

    NoIde schrieb:

    [...]
    Du kannst auch in der Header-Datei schauen welche Funktionen drin stecken. EIn Beispiel einer anderen Dll
    Aus der .h

    C-Quellcode

    1. BOOL BASSDEF(BASS_ChannelPlay)(DWORD handle, BOOL restart);

    So dann in .net, wobei die dll im selben Ordner wie die exe ist, wobei man of den marshal bemühen muss.

    VB.NET-Quellcode

    1. <DllImport("bass.dll")>
    2. Public Shared Function BASS_ChannelPlay(handle As Integer, restart As Boolean) As Boolean
    3. End Function

    [...]


    Der Vollständigkeit halber: Man kann nur exportierte Funktionen via P/Invoke aufrufen.
    Für alles weitere kann man dann die benötigte DLL via LoadLibrary laden und, entsprechendes Reverse-Engineering zum Ermitteln der genauen Funktionsadressen vorausgesetzt, die gewünschten Methoden via Function-Delegates aufgerufen werden.
    Jou, schon ein erwähnenswertes Detail. :thumbup:

    Das via LoadLibrary, werde ich mir auch mal anschauen, gute Gelegenheit das NSA-Tool(Ghidra) mal zu testen, wird im Moment ja als ernstzunehmende alternative zu IDA-Pro gewertet.

    @kiter20
    Ja die sios Seite ist sauber, hatte mir google bei meiner Suche garnet gezeigt.
    Cloud Computer? Nein Danke! Das ist nur ein weiterer Schritt zur totalen Überwachung.
    „Wer die Freiheit aufgibt, um Sicherheit zu gewinnen, wird am Ende beides verlieren.“
    Benjamin Franklin
    Binn ich hiermit auf dem richtigen Weg?
    Verstehe ich das richtig, das bei dem 2. Import der erste Wert "option" heißt?
    Aber das wird von VS bemängelt. Was kann ich da machen?

    Und verstehe ich das richtig? Ich mache das jetzt für jede Funktion die ich aus der dll benötige?

    VB.NET-Quellcode

    1. 'DLLFUNC int IfmDLLVersion()
    2. <DllImport("siosifm.dll")>
    3. Public Shared Function IfmDLLVersion() As Integer
    4. End Function
    5. 'DLLFUNC void IfmSetOption(int option, int param1)
    6. <DllImport("siosifm.dll")>
    7. Public Shared Function IfmSetOption(option As Integer, param1 As Integer)
    8. End Function
    "Mann" lernt mit seinen Projekten.
    Also wichtig sind Anzahl und Typ der Parameter, nicht der Name der Parameter. Der Funktionsname sollte übereinstimmen, muss aber nicht, dann musst du aber den EntryPoint nennen:

    VB.NET-Quellcode

    1. <DllImport("siosifm.dll", EntryPoint:="IfmDLLVersion")>
    2. Public Shared Function GetVersion() As Integer
    3. End Function

    Wobei du auch Option auch als Name für den Parameter nutzen kannst, musst dann nur eckige Klammern drum [Option] machen.

    Rein Theoretisch reichen die Funktionen die du brauchst, aber schöner ist alles zu implementieren, eine Wrapper-DLL zu machen. Wenn alles drin ist, kannste die auch bei anderen Projekten nutzen, wo diese Funktionen dann evtl. doch gebraucht werden, ohne die dll(oder nur Klasse) erneut bearbeiten zu müssen.
    Cloud Computer? Nein Danke! Das ist nur ein weiterer Schritt zur totalen Überwachung.
    „Wer die Freiheit aufgibt, um Sicherheit zu gewinnen, wird am Ende beides verlieren.“
    Benjamin Franklin

    xChRoNiKx schrieb:

    ein reserviertes Wort


    Auch resevierte Schlüsselworte kann man nutzen, muss man nur eckige klammern drum machen []. Macht nicht immer Sinn, aber das ist m.M.n. ein Sinnvolles Besipiel:

    VB.NET-Quellcode

    1. ClassX
    2. Public Sub [Stop] ()
    3. End Sub
    4. Public Sub Start ()
    5. End Sub
    6. End Class

    Cloud Computer? Nein Danke! Das ist nur ein weiterer Schritt zur totalen Überwachung.
    „Wer die Freiheit aufgibt, um Sicherheit zu gewinnen, wird am Ende beides verlieren.“
    Benjamin Franklin
    @NoIde danke. Wieder was dazu gelernt. Sehe grad deinen Beitrag über meinen der war als ich Antworten geklickst habe noch nicht da.
    Aber man kann ja entweder dann klammern drum machen oder es einfach anders nennen, ich finde es auch schöner ohne klammen und anderen Namen aber ich
    denke das ist wieder Ansichtssache.
    Grüße , xChRoNiKx

    Nützliche Links:
    Visual Studio Empfohlene Einstellungen | Try-Catch heißes Eisen
    Ja, wobei man die Klammern, wenn ich jetzt von meinem Beispiel ausgehe, nicht immer schreiben muss. Hat man eine Instanz der klasse, kann man ohne klammern arbeiten. Instanzvariable.Stop. Gibt da verschiedene Situationen, wo es Sinn machen kann. Allerdings, muss man dann oft Me.Stop oder [Stop] schreiben, wenn man innerhalb dieser Klasse drauf zugreift. Aber bleibt wie du sagst Geschmackssache, wobei ich das mag, aber trozdem immer die Goldwaage nutze, also neu abwägen tuh.
    Cloud Computer? Nein Danke! Das ist nur ein weiterer Schritt zur totalen Überwachung.
    „Wer die Freiheit aufgibt, um Sicherheit zu gewinnen, wird am Ende beides verlieren.“
    Benjamin Franklin
    Soweit so gut.
    Ich habe da mal was gemacht :D
    Bekomme aber natürlich einen Fehler. Ich bekomme das noch nicht so richtig in den Schädel, wie ich da vorgehen muss.
    Bei diesem Code: (IfmClose macht das Problem)

    VB.NET-Quellcode

    1. If cnt <= 0 Then
    2. txtOut.Text &= vbCrLf & ("A SIOS interferometer could not be found" & vbLf)
    3. IfmClose()
    4. Return
    5. End If​


    bekomme ich diese Meldung:
    System.Runtime.InteropServices.MarshalDirectiveException: "PInvoke-Einschränkung: Es können keine Varianten zurückgegeben werden."

    Und so sieht mein wrapper dafür aus.

    VB.NET-Quellcode

    1. <System.Runtime.InteropServices.DllImport("siosifm.dll", SetLastError:=False)>
    2. Public Shared Function IfmClose()
    3. End Function
    "Mann" lernt mit seinen Projekten.
    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!
    Ach verdammt. Einmal nicht als erstes dran gedacht ;)

    Aber weiter geht es:

    VB.NET-Quellcode

    1. devNo = IfmOpenUSB(0)
    2. If devNo < 0 Then
    3. ' txtOut.Text &= vbCrLf & ("Error during opening the device." & vbLf)
    4. IfmClose()
    5. Return
    6. End If


    VB.NET-Quellcode

    1. <System.Runtime.InteropServices.DllImport("siosifm.dll", SetLastError:=False)>
    2. Public Shared Function IfmOpenUSB(ByVal uniqueId As Integer) As Integer
    3. End Function


    Assistent für verwaltetes Debuggen "PInvokeStackImbalance" : "Ein Aufruf an die PInvoke-Funktion "SIOS!SIOS.Form1::IfmOpenUSB" 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."
    "Mann" lernt mit seinen Projekten.

    kiter20 schrieb:

    Einmal nicht als erstes dran gedacht
    Richte Dein Studio so ein, dass jedes neue Projekt auf Strict On steht.
    Studio one Projekt,
    Extras => Optionen => Projekte und Projektmappen => VB-Standard ...
    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!

    NoIde schrieb:

    Dann zeig uns mal wie die Funktion in der Doku steht


    IfmOpenUSB

    Syntax
    int IfmOpenUSB(int uniqueId)

    Description
    This function opens a device which is connected via the USB-interface for communication.

    Input parameters
    uniqueId The ID which describes the device. See IfmSearchUSBDevices for more information.

    Output Parameters
    The function returns an unique ID, the devNumber, which must be used to access the device by the future calls to the library. The devNumber is always a non negative number.
    In case of an error an error number is returned. Error numbers are always negative.

    _____________________________________________________
    IfmSearchUSBDevices

    Syntax
    int IfmSearchUSBDevices()

    Description
    The function IfmSearchUSBDevices looks for devices (this time only RE-10 cards) which are connected to the PC via the USB-Bus and returns the number of connected devices. These devices can be opened by IfmOpenUSB. For distinguishing between different devices the serial number can be accessed by the function IfmUSBDeviceSerial. IfmUSBDeviceSerial and IfmOpenUSB need an unique ID to select the desired device. This ID is the running number between zero and the device count minus one.

    Input parameters
    No input parameters.

    Output Parameters
    The function returns the devices count. Zero will be returned, if no device can be found. In case of an error a negative error number is returned.
    "Mann" lernt mit seinen Projekten.

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „kiter20“ ()

    Muss ich hiervon auch noch etwas beachten? Kommt aus der .h

    C-Quellcode

    1. ​#ifndef SIOSIFMDLL_H
    2. #define SIOSIFMDLL_H
    3. #ifdef _MSC_VER
    4. # pragma pack( push, packing )
    5. # pragma pack( 1 )
    6. # define PACK_STRUCT
    7. typedef __int64 int64;
    8. typedef __uint64 uint64;
    9. #elif defined( __GNUC__ )
    10. # define PACK_STRUCT __attribute__((packed))
    11. typedef long long int64;
    12. typedef unsigned long long uint64;
    13. #endif
    14. #ifdef _WIN32
    15. #ifdef DLLFUNC
    16. #define DLLFUNC extern "C" __declspec(dllexport)
    17. #else
    18. #define DLLFUNC extern "C" __declspec(dllimport)
    19. #endif
    20. #else
    21. #define DLLFUNC
    22. #endif
    23. #include <siosifmdef.h>
    "Mann" lernt mit seinen Projekten.