Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

Ich benötige etwas Hilfe bei der Eenbindung einer DLL

 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Windows-spezifische Fragen
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
AndreW



Anmeldungsdatum: 02.10.2022
Beiträge: 4
Wohnort: Chemnitz

BeitragVerfasst am: 02.10.2022, 06:04    Titel: Ich benötige etwas Hilfe bei der Eenbindung einer DLL Antworten mit Zitat

Hallo. Ich bin der André und brauche mal etwas Unterstützung.
Ich bin nicht so der Fachmann was Programmierung angeht, habe wor zg Jahren am C<64 mit Basic angefagen und über Qickbasic bis heute immer immer mal kleine Tools für mich geschrieben. Da ich im richtigen Leben Fahrdienstleiter und Stellwerker bei der Bahn bin hat es mich gereizt einmal ein Gleisbildstellwerk auf dem Pc nachzubauen das dann meine Modellbahn steuert. Dafür gibt es Relaiskarten die über die USB Schnittstelle ansteuerbar sind.

Das Programm dafür selbst habe ich erstellen können, nur mit der Einbindung der DLL um aus dem Programm heraus die Karte anzusteuern lässt mich verzweifeln.

Ich vermute das der Fehler wie so oft vor dem Bildschirm sitzt und ich einfach nur zu doof bin das richtig zu deklarieren. Deshalb meine Bitte um etwas Unterstützung.

Zur DLL gibt es folgende h Datei...
Code:

#ifndef USB_RELAY_DEVICE_H__
#define USB_RELAY_DEVICE_H__

#pragma comment(lib, "setupapi.lib")

#ifdef __cplusplus
extern "C" {
#endif

   //#pragma comment(lib, "setupapi.lib")

#ifdef _WIN32
#define EXPORT_API __declspec(dllexport)
#else
#define EXPORT_API
#endif

   enum usb_relay_device_type
   {
      USB_RELAY_DEVICE_ONE_CHANNEL = 1,
      USB_RELAY_DEVICE_TWO_CHANNEL = 2,
      USB_RELAY_DEVICE_FOUR_CHANNEL = 4,
      USB_RELAY_DEVICE_EIGHT_CHANNEL = 8   
   };

   /*usb relay board info structure*/
   struct usb_relay_device_info
   {
      unsigned char *serial_number;
      char *device_path;
      usb_relay_device_type type;
      usb_relay_device_info* next;
   };

   /*init the USB Relay Libary
   @returns: This function returns 0 on success and -1 on error.
   */
   int EXPORT_API usb_relay_init(void);
   
   /*Finalize the USB Relay Libary.
   This function frees all of the static data associated with
   USB Relay Libary. It should be called at the end of execution to avoid
   memory leaks.
   @returns:This function returns 0 on success and -1 on error.
   */
   int EXPORT_API usb_relay_exit(void);


   /*Enumerate the USB Relay Devices.*/
   struct usb_relay_device_info EXPORT_API * usb_relay_device_enumerate(void);


   /*Free an enumeration Linked List*/
   void EXPORT_API usb_relay_device_free_enumerate(struct usb_relay_device_info*);
   
   /*open device that serial number is serial_number*/
   /*@return: This funcation returns a valid handle to the device on success or NULL on failure.*/
   /*e.g: usb_relay_device_open_with_serial_number("abcde", 5")*/
   int EXPORT_API usb_relay_device_open_with_serial_number(const char *serial_number, unsigned len);

   /*open a usb relay device
   @return: This funcation returns a valid handle to the device on success or NULL on failure.
   */
   int EXPORT_API  usb_relay_device_open(struct usb_relay_device_info* device_info);

   /*close a usb relay device*/
   void EXPORT_API usb_relay_device_close(int hHandle);

   /*open a relay channel on the USB-Relay-Device
   @paramter: index -- which channel your want to open
   hHandle -- which usb relay device your want to operate
   @returns: 0 -- success; 1 -- error; 2 -- index is outnumber the number of the usb relay device
   */
   int EXPORT_API usb_relay_device_open_one_relay_channel(int hHandle, int index);

   /*open all relay channel on the USB-Relay-Device
   @paramter: hHandle -- which usb relay device your want to operate
   @returns: 0 -- success; 1 -- error
   */
   int EXPORT_API usb_relay_device_open_all_relay_channel(int hHandle);

   /*close a relay channel on the USB-Relay-Device
   @paramter: index -- which channel your want to close
   hHandle -- which usb relay device your want to operate
   @returns: 0 -- success; 1 -- error; 2 -- index is outnumber the number of the usb relay device
   */
   int EXPORT_API usb_relay_device_close_one_relay_channel(int hHandle, int index);

   /*close all relay channel on the USB-Relay-Device
   @paramter: hHandle -- which usb relay device your want to operate
   @returns: 0 -- success; 1 -- error
   */
   int EXPORT_API usb_relay_device_close_all_relay_channel(int hHandle);

   /*
   status bit: High --> Low 0000 0000 0000 0000 0000 0000 0000 0000, one bit indicate a relay status.
   the lowest bit 0 indicate relay one status, 1 -- means open status, 0 -- means closed status.
   bit 0/1/2/3/4/5/6/7/8 indicate relay 1/2/3/4/5/6/7/8 status
   @returns: 0 -- success; 1 -- error
   */
   int EXPORT_API usb_relay_device_get_status(int hHandle, unsigned int *status);

#ifndef EXPORT_DLL
   int EXPORT_API usb_relay_device_set_serial(int hHandle, char serial[5]);
#endif

#ifdef __cplusplus
}
#endif

#endif //end of ifdef __cplusplus


ich habe dann mir folgende bi erarbeitet.
Code:

#INCLIB "usb_relay_device"


DECLARE FUNCTION usb_relay_init LIB "usb_relay_device" ALIAS "usb_relay_init" _
   ()As Integer
   
   
DECLARE FUNCTION usb_device_open LIB "usb_relay_device" ALIAS "usb_relay_device_open_with_serial_number" _
   (ByRef serial_number As String,ByRef lenght As Integer)  As integer
   
Declare FUNCTION usb_device_close LIB "usb_relay_device" ALIAS "usb_relay_device_close" _
   (ByRef serial_number As String)
   
Declare Function usb_relay_open  LIB "usb_relay_device" ALIAS "usb_relay_device_open_one_relay_channel" _
(ByRef hHandle As integer, ByRef index As Integer)As Integer

Declare Function usb_relay_close  LIB "usb_relay_device" ALIAS "usb_relay_device_close_one_relay_channel" _
(ByRef hHandle As integer, ByRef index As Integer)As Integer


Ich vermute das ich irgendwie etwas grundsätzlich nicht richtig verstanden habe und einfach die falschen Datentypen deklariert habe. Den Ansprechen lässt sich die Karte nicht und Freebasic stürzt gern ohne Fehlermeldung nach dem Kompilieren ab.


Die Funktion
usb_relay_device_free_enumerate
habe ich jetzt noch nicht deklariert da ich die Serial der Karte bereits kenne. Ich vermute das diese mir ein Array ausgibt aus dem ich dann die Serials der angesteckten Karten auslesen kann.

Wäre wirklich toll wenn mir jemand da mal auf die Sprünge helfen kann.
es gänge zwar ganz zur Not mit einem kleinen Tool zur Karte, das ich aus dem Programm mittels Shell aufrufen könnte, aber wirklich elegant ist das nicht, zumal sich dann ja jedes mal kurz die Konsole öffnet.
Lg André
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1208
Wohnort: Ruhrpott

BeitragVerfasst am: 02.10.2022, 20:40    Titel: Antworten mit Zitat

Hallo AndreW und willkommen im Forum lächeln

Da hast du dir ja für den Anfang was ganz schön schweres vorgenommen. grinsen

Ganz so einfach ist das Portieren einer Headerdatei dann doch nicht, aber auch kein Hexenwerk, man sollte sich allerdings etwas mit C auskennen. Hier meine Übersetzung (nach bestem Wissen und ohne Anspruch auf Fehlerfreiheit), wobei ich die Originaldeklarationen der Anschaulichkeit wegen auskommentiert dringelassen habe:
Code:
#Ifndef USB_RELAY_DEVICE_H__
#define USB_RELAY_DEVICE_H__
#EndIf

'   //#Pragma comment(Lib, "setupapi.lib")

#Ifdef _WIN32
#define EXPORT_API __declspec(dllexport)
#Else
#define EXPORT_API
#EndIf

Extern "C"
   
   Enum usb_relay_device_type
     USB_RELAY_DEVICE_ONE_CHANNEL = 1,
     USB_RELAY_DEVICE_TWO_CHANNEL = 2,
     USB_RELAY_DEVICE_FOUR_CHANNEL = 4,
     USB_RELAY_DEVICE_EIGHT_CHANNEL = 8   
   End Enum
   
   '/*usb relay board info structure*/
   Type usb_relay_device_info
     As ZString Ptr serial_number
     As ZString Ptr device_path
     As usb_relay_device_type Type
     As usb_relay_device_info Ptr Next
   End Type
   
   '/*init the USB Relay Libary
   '@returns: This Function returns 0 On success And -1 On error.
   '*/
   'Int EXPORT_API usb_relay_init(void);
   Dim usb_relay_init As Function () As Long
   
   '/*Finalize the USB Relay Libary.
   'This Function frees all of the Static Data associated With
   'USB Relay Libary. It should be called at the End of execution To avoid
   'memory leaks.
   '@returns:This Function returns 0 On success And -1 On error.
   '*/
   'Int EXPORT_API usb_relay_exit(void);
   Dim usb_relay_exit As Function () As Long

   '/*Enumerate the USB Relay Devices.*/
   'struct usb_relay_device_info EXPORT_API * usb_relay_device_enumerate(void);
   Dim usb_relay_device_enumerate As Function() As usb_relay_device_info Ptr

   '/*Free an enumeration Linked List*/
   'void EXPORT_API usb_relay_device_free_enumerate(struct usb_relay_device_info*);
   Dim usb_relay_device_free_enumerate As Sub (As usb_relay_device_info Ptr)
   
   '/*Open device that serial number Is serial_number*/
   '/*@Return: This funcation returns a valid handle To the device On success Or NULL On failure.*/
   '/*e.g: usb_relay_device_open_with_serial_number("abcde", 5")*/
   'Int EXPORT_API usb_relay_device_open_with_serial_number(Const char *serial_number, Unsigned Len);
   Dim usb_relay_device_open_with_serial_number As Function(serial_number As ZString Ptr, As ULong) As Long

   '/*Open a usb relay device
   '@Return: This funcation returns a valid handle To the device On success Or NULL On failure.
   '*/
   'Int EXPORT_API  usb_relay_device_open(struct usb_relay_device_info* device_info);
   Dim usb_relay_device_open As Function(device_info As usb_relay_device_info Ptr) As Long

   '/*Close a usb relay device*/
   'void EXPORT_API usb_relay_device_close(Int hHandle);
   Dim usb_relay_device_close As Sub(hHandle As Long)

   '/*Open a relay channel On the USB-Relay-Device
   '@paramter: index -- which channel your want To Open
   'hHandle -- which usb relay device your want To operate
   '@returns: 0 -- success; 1 -- Error; 2 -- index Is outnumber the number of the usb relay device
   '*/
   'Int EXPORT_API usb_relay_device_open_one_relay_channel(Int hHandle, Int index);
   Dim usb_relay_device_open_one_relay_channel As Function(hHandle As Long, index As Long) As Long

   '/*Open all relay channel On the USB-Relay-Device
   '@paramter: hHandle -- which usb relay device your want To operate
   '@returns: 0 -- success; 1 -- Error
   '*/
   'Int EXPORT_API usb_relay_device_open_all_relay_channel(Int hHandle);
   Dim usb_relay_device_open_all_relay_channel As Function(hHandle As Long) As Long

   '/*Close a relay channel On the USB-Relay-Device
   '@paramter: index -- which channel your want To Close
   'hHandle -- which usb relay device your want To operate
   '@returns: 0 -- success; 1 -- Error; 2 -- index Is outnumber the number of the usb relay device
   '*/
   'Int EXPORT_API usb_relay_device_close_one_relay_channel(Int hHandle, Int index);
   Dim usb_relay_device_close_one_relay_channel As Function(hHandle As Long, index As Long) As Long

   '/*Close all relay channel On the USB-Relay-Device
   '@paramter: hHandle -- which usb relay device your want To operate
   '@returns: 0 -- success; 1 -- Error
   '*/
   'Int EXPORT_API usb_relay_device_close_all_relay_channel(Int hHandle);
   Dim usb_relay_device_close_all_relay_channel As Function(hHandle As Long) As Long

   '/*
   'status Bit: High --> Low 0000 0000 0000 0000 0000 0000 0000 0000, one Bit indicate a relay status.
   'the lowest Bit 0 indicate relay one status, 1 -- means Open status, 0 -- means closed status.
   'Bit 0/1/2/3/4/5/6/7/8 indicate relay 1/2/3/4/5/6/7/8 status
   '@returns: 0 -- success; 1 -- Error
   '*/
   'Int EXPORT_API usb_relay_device_get_status(Int hHandle, Unsigned Int *status);
   Dim usb_relay_device_get_status As Function(hHandle As Long, status As ULong Ptr) As Long

   #Ifndef EXPORT_DLL
      'Int EXPORT_API usb_relay_device_set_serial(Int hHandle, char serial[5]);
      Dim usb_relay_device_set_serial As Function(hHandle As Long, serial As ZString) As Long
   #EndIf

End Extern


Damit ist es allerdings noch nicht getan, du mußt die Funktionen der dll auch noch entsprechend in dein FB-Programm einbinden. Zur Demonstration habe ich mal eine Funktion herausgegriffen und damit eine eigene kleine test-dll erstellt.
Code:
Extern "c"
Function usb_relay_device_open_with_serial_number Alias "usb_relay_device_open_with_serial_number"(serial_number As ZString Ptr, nummer As ULong) As Long Export
   Print *serial_number
   Print nummer
   Return -1
End Function
End Extern
Speichere diesen Programmschnippsel bitte unter dem Namen "gbDll.bas" und kompiliere ihn (nur kompilieren, nicht ausführen!) mit der Option "-dll".

Und so werden die dll-Funktionen eingebunden und aufgerufen:
Code:
'dll-test

#Include "Gleisbild.bi"

Dim As Any Ptr header 'pointer auf die dll-Datei
header = DylibLoad("gbDll.dll") 'dll-datei einbinden
usb_relay_device_open_with_serial_number = DylibSymbol(header, "usb_relay_device_open_with_serial_number") 'funktion der dll für das programm nutzbar machen

'zwei testvariablen
Dim As ZString*20 teststring = "Hallo Welt"
Dim As Long testlong = 20

'funktion der dll mit testvariablen als argumente aufrufen
Print usb_relay_device_open_with_serial_number(@teststring, testlong)

Sleep
Wenn alles richtig funktioniert, muss nach dem Aufruf

Hallo Welt
20
-1

auf dem Bildschirm stehen.

Ich hoffe, das war anschaulich genung.

Viel Vergnügen beim Eisenbahnspielen. lächeln

Gruß
grindstone
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
AndreW



Anmeldungsdatum: 02.10.2022
Beiträge: 4
Wohnort: Chemnitz

BeitragVerfasst am: 02.10.2022, 21:00    Titel: Antworten mit Zitat

Vielen Dank für die Hilfe.
Ich gebe zu das ich mir das wirklich einfacher vorgestellt habe.
So ist das wenn man Naiv glaubt das zurecht basteln zu können.
grinsen

Da versuche ich mal mein Glück.
Gruß André
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
AndreW



Anmeldungsdatum: 02.10.2022
Beiträge: 4
Wohnort: Chemnitz

BeitragVerfasst am: 02.10.2022, 22:15    Titel: Antworten mit Zitat

Kurze Rückmeldung..
Ich habe es hinbekommen. Vielen vielen Dank...

Wenn ich mein Programm fertig habe und alles soweit kommentiert das es nachvollziehbar ist, kann ich es bei Interesse ja mal vorstellen.
Ist vielleicht ja mal interessant.

Für den Fall das nochmals jemand vor dem Problem steht hier meine
Usbrelais.bi
Code:
#INCLIB "usb_relay_device"

DECLARE Function usb_relay_init LIB "usb_relay_device" ALIAS "usb_relay_init"()As long

DECLARE FUNCTION usb_device_open LIB "usb_relay_device" ALIAS "usb_relay_device_open_with_serial_number" _
(serial_number As ZString Ptr, As ULong) As Long
     
Declare sub usb_device_close LIB "usb_relay_device" ALIAS "usb_relay_device_close" _
(hHandle As Long)
   
Declare Function usb_relay_open  LIB "usb_relay_device" ALIAS "usb_relay_device_open_one_relay_channel" _
(hHandle As Long, index As Long) As Long

Declare Function usb_relay_close  LIB "usb_relay_device" ALIAS "usb_relay_device_close_one_relay_channel" _
(hHandle As Long, index As Long) As Long


sowie die Subs mit dehnen ich das steuere..

Code:

Sub USBRelaisopen(serial As String, channel As Long)
usb_relay_init()
dim relays as Long
relays = usb_device_open(serial,len(serial))
usb_relay_open(relays,channel)
 usb_device_close(relays)   
End Sub
Sub USBRelaisclose(serial As String, channel As Long)
        usb_relay_init()
dim relays as Long
relays = usb_device_open(serial,len(serial))
usb_relay_close(relays,channel)
 usb_device_close(relays)   
End Sub




und weil es ja vielleicht mal interessant ist, mal ein Beispiel wo ich das brauche.. Die Logik an einem Einfahrsignal.

Code:

 'Signal A(
                   Case siga
                   'Signaltaste Einfahrsignal A
                           If msg.message = WM_LBUTTONDOWN Then
                 
                     If getflag(fsb ,"bb") = 0 And getflag(Fsc ,"cc") = 0 Then   
                             'Prüfung ob gegenläufige Fahrstraße eingestellt ist (Signal B oder C)
                     If getflag(fsa ,"aa") = 0 Then
                              'Prüfung ob bereits eine Fahrstraße von A eingestellt ist.. (zb auf Gleis 2)
                             If getflag(g1bes,"xx") = 1 And getflag(W1_lage ,"W1") = 0 Then
                               MessageBox(0, "Gleis 1  besetzt!", _
                               
"**TUEFA**", _
MB_ok Or MB_ICONEXCLAMATION Or MB_DEFBUTTON2 OR MB_SYSTEMMODAL) 
    'Prüfung ob das Gleis 1 besetzt ist, wenn ja dann Fehlermeldung
                             
                             ElseIf  getflag(g2bes,"xx") = 1 And getflag(W1_lage ,"W1") = 1 Then
                                MessageBox(0, "Gleis 2  besetzt!", _
"**TUEFA**", _
MB_ok Or MB_ICONEXCLAMATION Or MB_DEFBUTTON2 OR MB_SYSTEMMODAL)
    'Prüfung ob das Gleis 2 besetzt ist, wenn ja dann Fehlermeldung
                             Else
                                     ' wenn beides nein das Signal im Pult auf Fahrt und Fahrstraße festlegen.
                                     ' Relais schalten
picture_Set(Window_Abfrage,c2,"bmp\esigs2.bmp")
picture_Set(Window_Abfrage,c1,"bmp\vs2.bmp")
Setflag(fsa ,"aa")
usb_relay_open(relai1,01)

                             EndIf
                             
                           
                     Else 
                              'Ist eine Fahrstraße eingestellt dann diese auflösen, Signal im Pult auf Halt stellen
                             'und betreffendes Gleis als Besetzt markieren (Ein/Ausfahrsperre), Relais schalten
picture_Set(Window_Abfrage,c2,"bmp\esigs1.bmp")
picture_Set(Window_Abfrage,c1,"bmp\vs1.bmp")
Setflag(fsa ,"a0")
usb_relay_close(relai1,01)
 
 If getflag(W1_lage ,"W1") = 1 Then
        setflag(g2bes,"xx")
        picture_Set(Window_Abfrage,e8,"bmp\gbesetzt.bmp")
       
EndIf
If getflag(W1_lage ,"W1") = 0 Then
        setflag(g1bes,"xx")
        picture_Set(Window_Abfrage,d6,"bmp\gbesetzt.bmp")
        picture_Set(Window_Abfrage,d7,"bmp\gbesetzt.bmp")
        picture_Set(Window_Abfrage,d8,"bmp\gbesetzt.bmp")
EndIf
                    EndIf
                     EndIf
               
                           EndIf



dazu gibt es eine FUNCTION sowie eine SUB die in einer Datei Bytes setzen und auslesen und somit den Ist-Zustand speichern der dann jederzeit abgefragt werden kann und bei Programmneustart natürlich wieder da ist.
Code:

Function getflag(adress As Integer,flag As String) As Integer
Dim n As Integer
Dim f2 As Integer = FreeFile
Dim flagcheck As String * 2
Open Speicher For Binary As #f2
    Get #f2,adress,flagcheck
  Close #f2   
    If flagcheck = flag Then

 n = 1
    Else
 n = 0   
    EndIf
    Return n
 End Function
 
 Sub setflag(adress As Integer,flag As String )
 Dim f2 As Integer = FreeFile       
 Open Speicher For Binary As #f2
 Put #f2,adress,flag
 Close #f2 

 End Sub


Und so sieht das ganze dann aus...


Lg André
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1208
Wohnort: Ruhrpott

BeitragVerfasst am: 03.10.2022, 09:14    Titel: Antworten mit Zitat

Na gut, statisch verlinken geht natürlich auch... zwinkern

Nur mal aus Neugierde: Woher stammt deine dll "usb_relay_device"? Wenn sie von einem C-Compiler erzeugt worden wäre, würden deine Deklarationen ohne EXTERN "C" bzw. "CDECL" nicht funktioneren.

Nach #INCLIB kannst du dir übrigens das LIB in jeder Deklaration sparen (es schadet allerdings auch nicht).

Wenn du dein Programm, eventuell auch mit einer genaueren Beschreibung der Hardware, vorstellen möchtest, wir haben dafür eine eigene Rubrik Projektvorstellungen.

Gruß
grindstone
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
AndreW



Anmeldungsdatum: 02.10.2022
Beiträge: 4
Wohnort: Chemnitz

BeitragVerfasst am: 04.10.2022, 02:49    Titel: Antworten mit Zitat

Hallo.

Die Dll war als Download zu der Relaiskarte dazu.
Ursprung denke ich China..

Zur der Vorstellung komme ich dann zurück wenn das Ding dann die Modellbahn im Griff hat.
lächeln

Lg. André
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Windows-spezifische Fragen Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

 Impressum :: Datenschutz