dll. mehrmals ein einem Programm unabhängig Nutzen

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

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

    dll. mehrmals ein einem Programm unabhängig Nutzen

    Hallo,

    Habe eine I/O Usb Karte, Man kann laut Hersteller bis zu 4 Stück an einem Computer anschließen und ansteuern. Gibt also 4 Adressen. Wie ich die aber alle gleichzeitig in einem Programm unterbringe, dazu schreibt der Hersteller leider nix. Wenn ich Alle 4 Karten in unterschiedlichen Modulen nacheinander verbinde, kann er alle finden. aber wenn ich dann einen Ausgang an mache , über das jeweilige modul, reagiert nur die Letzte karte.


    Da ich überhaupt keinen lösungsansatz habe Hier der Quellcode, ein wechseln zwischen den Karten geht nicht, da auch Daten von den Karten kommen und ich die nicht beeinflussen kann.

    VB.NET-Quellcode

    1. ​Module Verbindungen_und_KomunikationKüche
    2. Private Declare Function OpenDevice Lib "k8055d.dll" (ByVal CardAddress As Integer) As Integer
    3. Private Declare Sub CloseDevice Lib "k8055d.dll" ()
    4. Private Declare Function Version Lib "k8055d.dll" () As Integer
    5. Private Declare Function SearchDevices Lib "k8055d.dll" () As Integer
    6. Private Declare Function SetCurrentDevice Lib "k8055d.dll" (ByVal CardAddress As Integer) As Integer
    7. Private Declare Function ReadAnalogChannel Lib "k8055d.dll" (ByVal Channel As Integer) As Integer
    8. Private Declare Sub ReadAllAnalog Lib "k8055d.dll" (ByRef Data1 As Integer, ByRef Data2 As Integer)
    9. Private Declare Sub OutputAnalogChannel Lib "k8055d.dll" (ByVal Channel As Integer, ByVal Data As Integer)
    10. Private Declare Sub OutputAllAnalog Lib "k8055d.dll" (ByVal Data1 As Integer, ByVal Data2 As Integer)
    11. Private Declare Sub ClearAnalogChannel Lib "k8055d.dll" (ByVal Channel As Integer)
    12. Private Declare Sub SetAllAnalog Lib "k8055d.dll" ()
    13. Private Declare Sub ClearAllAnalog Lib "k8055d.dll" ()
    14. Private Declare Sub SetAnalogChannel Lib "k8055d.dll" (ByVal Channel As Integer)
    15. Private Declare Sub WriteAllDigital Lib "k8055d.dll" (ByVal Data As Integer)
    16. Private Declare Sub ClearDigitalChannel Lib "k8055d.dll" (ByVal Channel As Integer)
    17. Private Declare Sub ClearAllDigital Lib "k8055d.dll" ()
    18. Private Declare Sub SetDigitalChannel Lib "k8055d.dll" (ByVal Channel As Integer)
    19. Private Declare Sub SetAllDigital Lib "k8055d.dll" ()
    20. Private Declare Function ReadDigitalChannel Lib "k8055d.dll" (ByVal Channel As Integer) As Boolean
    21. Private Declare Function ReadAllDigital Lib "k8055d.dll" () As Integer
    22. Private Declare Function ReadCounter Lib "k8055d.dll" (ByVal CounterNr As Integer) As Integer
    23. Private Declare Sub ResetCounter Lib "k8055d.dll" (ByVal CounterNr As Integer)
    24. Private Declare Sub SetCounterDebounceTime Lib "k8055d.dll" (ByVal CounterNr As Integer, ByVal DebounceTime As Integer)
    25. Public Sub VerbindenKüche()
    26. Dim CardAddress As Integer
    27. Dim h As Integer
    28. CardAddress = 2
    29. h = OpenDevice(CardAddress)
    30. Select Case h
    31. Case 0, 1, 2, 3
    32. Form1.VerbundenKüche = "1"
    33. Case -1
    34. Form1.VerbundenKüche = "0"
    35. End Select
    36. End Sub
    37. Public Sub test1()
    38. SetAllDigital()
    39. End Sub
    40. End Module



    VB.NET-Quellcode

    1. ​Module Verbindungen_und_Komunikation
    2. Private Declare Function OpenDevice Lib "k8055d.dll" (ByVal CardAddress As Integer) As Integer
    3. Private Declare Sub CloseDevice Lib "k8055d.dll" ()
    4. Private Declare Function Version Lib "k8055d.dll" () As Integer
    5. Private Declare Function SearchDevices Lib "k8055d.dll" () As Integer
    6. Private Declare Function SetCurrentDevice Lib "k8055d.dll" (ByVal CardAddress As Integer) As Integer
    7. Private Declare Function ReadAnalogChannel Lib "k8055d.dll" (ByVal Channel As Integer) As Integer
    8. Private Declare Sub ReadAllAnalog Lib "k8055d.dll" (ByRef Data1 As Integer, ByRef Data2 As Integer)
    9. Private Declare Sub OutputAnalogChannel Lib "k8055d.dll" (ByVal Channel As Integer, ByVal Data As Integer)
    10. Private Declare Sub OutputAllAnalog Lib "k8055d.dll" (ByVal Data1 As Integer, ByVal Data2 As Integer)
    11. Private Declare Sub ClearAnalogChannel Lib "k8055d.dll" (ByVal Channel As Integer)
    12. Private Declare Sub SetAllAnalog Lib "k8055d.dll" ()
    13. Private Declare Sub ClearAllAnalog Lib "k8055d.dll" ()
    14. Private Declare Sub SetAnalogChannel Lib "k8055d.dll" (ByVal Channel As Integer)
    15. Private Declare Sub WriteAllDigital Lib "k8055d.dll" (ByVal Data As Integer)
    16. Private Declare Sub ClearDigitalChannel Lib "k8055d.dll" (ByVal Channel As Integer)
    17. Private Declare Sub ClearAllDigital Lib "k8055d.dll" ()
    18. Private Declare Sub SetDigitalChannel Lib "k8055d.dll" (ByVal Channel As Integer)
    19. Private Declare Sub SetAllDigital Lib "k8055d.dll" ()
    20. Private Declare Function ReadDigitalChannel Lib "k8055d.dll" (ByVal Channel As Integer) As Boolean
    21. Private Declare Function ReadAllDigital Lib "k8055d.dll" () As Integer
    22. Private Declare Function ReadCounter Lib "k8055d.dll" (ByVal CounterNr As Integer) As Integer
    23. Private Declare Sub ResetCounter Lib "k8055d.dll" (ByVal CounterNr As Integer)
    24. Private Declare Sub SetCounterDebounceTime Lib "k8055d.dll" (ByVal CounterNr As Integer, ByVal DebounceTime As Integer)
    25. Public Sub VerbindenBad()
    26. Dim CardAddress As Integer
    27. Dim h As Integer
    28. CardAddress = 0
    29. h = OpenDevice(CardAddress)
    30. Select Case h
    31. Case 0, 1, 2, 3
    32. Form1.VerbundenBad = "1"
    33. Case -1
    34. Form1.VerbundenBad = "0"
    35. End Select
    36. End Sub
    37. Public Sub Test()
    38. SetAllDigital()
    39. End Sub
    40. End Module




    VB.NET-Quellcode

    1. ​Public Class Form1
    2. Public VerbundenBad As Integer 'Adresse 0
    3. Public VerbundenWohnzimmer As Integer 'Adresse 1
    4. Public VerbundenKüche As Integer ''Adresse 2
    5. Public VerbundenSchlafzimmer As Integer ' Adresse 3
    6. Public LichtBad0 As Integer
    7. Public LichtBad1 As Integer
    8. Public LichtBad2 As Integer
    9. Public RauchmelderBad As CheckBox
    10. Public BewegungsmelderBad As CheckBox
    11. Public LichtschalterBad0 As CheckBox
    12. Public LichtschalterBad1 As CheckBox
    13. Public LichtschalterBad2 As CheckBox
    14. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    15. VerbindenBad()
    16. VerbindenKüche()
    17. VerbindenSchlafzimmer()
    18. VerbindenWohnzimmer()
    19. MsgBox(VerbundenBad & VerbundenKüche & VerbundenSchlafzimmer & VerbundenWohnzimmer)
    20. End Sub
    21. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    22. Test()
    23. End Sub
    24. Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    25. test1()
    26. End Sub
    27. End Class
    @KAXTJ Es sieht mir so aus, als ob der Parameter Channel die einzelnen Kanäle unterscheidet.
    Funktionen mit
    *Device* sprechen wohl eine Karte bzw. einen USB-Stecker an.
    Allerdings ist es merkwürdig, dass dann die Prozeduren SetAllAnalog() und ClearAllAnalog() keine Parameter haben.
    Um was genaues sagen zu können, müsste man die Hardware haben, um das zu untersuchen.

    KAXTJ schrieb:

    Wenn ich Alle 4 Karten in unterschiedlichen Modulen nacheinander verbinde, kann er alle finden.
    Ich denke fast, er findet nur den letzten, der noch frei ist, die anderen sind dann blockiert.
    Mit mehreren Moduls kannst Du da nix machen, pack die Prozeduren mal in eine Klasse.
    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!

    KAXTJ schrieb:

    Wenn ich Alle 4 Karten in unterschiedlichen Modulen nacheinander verbinde, kann er alle finden. aber wenn ich dann einen Ausgang an mache , über das jeweilige modul, reagiert nur die Letzte karte.

    Das ist das normale und vom Hersteller offenbar gewünschte Verhalten der DLL. Wenn man reinschaut, sieht man, dass OpenDevice() für jede der 4 möglichen Adressen einen internen Speicherslot besitzt. Darin speichert die Funktion das Handle, das beim internen Aufruf von CreateFile zurückkommt. Außerdem gibt es eine globale Variable, die das aktuell verwendete Gerät speichert. Auf dieses wirken sich alle Aufrufe der DLL aus, bis du durch Aufruf von SetCurrentDevice() eine andere Karte wählst. Möchtest du also alle digitalen Ausgänge an allen Karten auf high setzen, musst du folgendes tun:

    VB.NET-Quellcode

    1. OpenDevice(0)
    2. OpenDevice(1)
    3. OpenDevice(2)
    4. OpenDevice(3)
    5. SetCurrentDevice(0)
    6. SetAllDigital()
    7. SetCurrentDevice(1)
    8. SetAllDigital()
    9. SetCurrentDevice(2)
    10. SetAllDigital()
    11. SetCurrentDevice(3)
    12. SetAllDigital()

    Fazit: Die DLL ist stümperhaft programmiert. So ziemlich alle Daten liegen in globalen Variablen, was die parallele Nutzung mehrerer Karten erschwert. Besser wäre es, wenn OpenDevice() das Handle zurückgeben und alle Steuerfunktionen dieses als ersten Parameter akzeptieren würden. Dann wäre sogar eine beliebige Anzahl an Karten möglich, nicht nur 4.

    Die Ansteuerung aus der DLL kannst du dir prinzipiell auch selbst schreiben. Den Inhalt der Funktionen kann man fast erraten:

    Quellcode

    1. handle = OpenDevice(id) --> CreateFile(someName + id, someFlags)
    2. CloseDevice() --> CloseHandle(handle)
    3. Set*Something(data) --> WriteFile(handle, someFunctionCode, data)
    4. Get*Something() --> ReadFile(handle, someFunctionCode, bufferToReturn)
    Gruß
    hal2000
    Eine Möglichkeit wäre die DLL noch unter 3 anderen Namen zu speichern.

    k8055d.dll
    k8055d_1.dll
    k8055d_2.dll
    k8055d_3.dll

    VB.NET-Quellcode

    1. 'Deklaration für die erste DLL:
    2. Private Declare Function OpenDevice Lib "k8055d.dll" (ByVal CardAddress As Integer) As Integer
    3. Private Declare Sub CloseDevice Lib "k8055d.dll" ()
    4. Private Declare Function Version Lib "k8055d.dll" () As Integer
    5. Private Declare Function SearchDevices Lib "k8055d.dll" () As Integer
    6. '... usw.
    7. 'Deklaration für die zweite DLL:
    8. Private Declare Function OpenDevice_1 Lib "k8055d_1.dll" Alias "OpenDevice" (ByVal CardAddress As Integer) As Integer
    9. Private Declare Sub CloseDevice_1 Lib "k8055d_1.dll" Alias "CloseDevice" ()
    10. Private Declare Function Version_1 Lib "k8055d_1.dll" Alias "Version" () As Integer
    11. Private Declare Function SearchDevices_1 Lib "k8055d_1.dll" Alias "SearchDevices" () As Integer
    12. '... usw.
    13. 'Deklaration für die dritte DLL:
    14. Private Declare Function OpenDevice_2 Lib "k8055d_2.dll" Alias "OpenDevice" (ByVal CardAddress As Integer) As Integer
    15. '... usw.
    16. 'Deklaration für die vierte DLL:
    17. Private Declare Function OpenDevice_3 Lib "k8055d_3.dll" Alias "OpenDevice" (ByVal CardAddress As Integer) As Integer
    18. '... usw.
    19. ...
    20. Dim h As Integer
    21. h = OpenDevice(0)
    22. Dim h1 As Integer
    23. h1 = OpenDevice_1(1)
    24. Dim h2 As Integer
    25. h2 = OpenDevice_2(2)
    26. Dim h3 As Integer
    27. h3 = OpenDevice_3(3)
    28. ...
    29. ...
    30. Public Sub Test()
    31. SetAllDigital()
    32. SetAllDigital_1()
    33. SetAllDigital_2()
    34. SetAllDigital_3()
    35. End Sub
    36. ...
    @Eierlein Das dürfte auch vor die Hose gehen, da die DLLs immer auf dieselbe Hardware zugreifen. :/
    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!