From 63e458581bd3d7a9a2dd04523c933653fb7e1adb Mon Sep 17 00:00:00 2001 From: "Pavel A." Date: Thu, 15 Jan 2015 02:22:47 +0200 Subject: [PATCH] usb-relay-dll: added extras for scripting, fixed cdecl Added helper methods for python, etc; _cdecl should be __cdecl. Built with vs2013 32/64. Lib version -> 2.0. --- doc/Readme_USB-Relay-DLL.md | 29 +++++++++++++++++-- lib/usb_relay_device.h | 55 +++++++++++++++++++++++++++++-------- lib/usb_relay_lib.c | 49 ++++++++++++++++++++++++++++++--- 3 files changed, 115 insertions(+), 18 deletions(-) diff --git a/doc/Readme_USB-Relay-DLL.md b/doc/Readme_USB-Relay-DLL.md index ce7888b..9eff40d 100644 --- a/doc/Readme_USB-Relay-DLL.md +++ b/doc/Readme_USB-Relay-DLL.md @@ -1,12 +1,13 @@ How to use USB_RELAY_DEVICE DLL =============================== -Version 1.0 +Version 2.0 Changes to the original DLL: ---------------------------- - Type used for handles changed from int to intptr_t, for 64-bit compatibility. This should be binary compatible with existing 32-bit clients. + - Added helper functions for managed callers and scripts (see below) Windows, Visual C++ applications @@ -71,9 +72,33 @@ Using the API: Closes the Relay device handle opened by `usb_relay_device_open()` or `usb_relay_device_open_with_serial_number()` -* `usb_relay_exit` + * `usb_relay_exit` Finalizes the library + + +Helper functions for managed callers and scripts +------------------------------------------------ + +These functions help to use this lib in managed languages. +Native C or C++ callers do not need to use these. +The ptr_usb_relay_device_info parameter is pointer to `struct usb_relay_device_info`, converted to a pointer-sized integer. +Type `int` means the "C" integer (which usually is 32-bit), `ptr` is a pointer-sized integer. + + * `ptr_usb_relay_device_info usb_relay_device_next_dev(ptr_usb_relay_device_info)` + Returns pointer to the next element of device list obtained from `usb_relay_device_enumerate` + + * `int usb_relay_device_get_num_relays(ptr_usb_relay_device_info)` + Returns number of relay channels on the device. Values <= 0 are not valid and mean error. + + * `ptr usb_relay_device_get_id_string(ptr_usb_relay_device_info)` + Returns the "serial number" string of the device, as pointer to constant C string (one-byte characters, null terminated). + + * `int USBRL_API usb_relay_device_lib_version()` + Returns the version of the library. + The lower 16 bits are the library version. Higher bits: undefined, ignore. + + Error handling --------------- If error occurred, the API functions that return error code return -1; diff --git a/lib/usb_relay_device.h b/lib/usb_relay_device.h index 7250fcc..7e2ca01 100644 --- a/lib/usb_relay_device.h +++ b/lib/usb_relay_device.h @@ -4,23 +4,29 @@ #define USBRELAY_LIB_VER 0x02 #ifdef WIN32 +#ifdef _MSC_VER /* Microsoft compiler: */ +# #ifndef USBRL_CALL -# define USBRL_CALL _cdecl +# define USBRL_CALL __cdecl #endif #ifndef USBRL_API # define USBRL_API __declspec(dllimport) USBRL_CALL +# pragma comment(lib, "usb_relay_device") #endif # -#else /* !WIN32 */ -# +#else /* Windows & Not Microsoft's compiler */ +# define USBRL_CALL +# define USBRL_API USBRL_CALL +#endif /* Windows & Not Microsoft's compiler */ +#endif /* WIN32 */ + #ifndef USBRL_CALL # define USBRL_CALL #endif #ifndef USBRL_API # define USBRL_API USBRL_CALL #endif -# -#endif /* WIN32 */ + #include @@ -29,11 +35,11 @@ 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_DEVICE_EIGHT_CHANNEL = 8 }; -/** USB relay board info structure*/ +/** USB relay board info structure */ struct usb_relay_device_info { char *serial_number; @@ -60,11 +66,13 @@ It should be called at the end of execution to avoid memory leaks. */ int USBRL_API usb_relay_exit(void); -/** Enumerate the USB Relay Devices.*/ +/** Enumerate the USB Relay Devices. +@return Pointer to list of usb_relay_device_info + Caller should free it with usb_relay_device_free_enumerate +*/ pusb_relay_device_info_t USBRL_API usb_relay_device_enumerate(void); - -/** Free an enumeration Linked List*/ +/** Free an enumeration Linked List */ void USBRL_API usb_relay_device_free_enumerate(struct usb_relay_device_info*); /** Open device that serial number is serial_number @@ -77,7 +85,7 @@ intptr_t USBRL_API usb_relay_device_open_with_serial_number(const char *serial_n */ intptr_t USBRL_API usb_relay_device_open(struct usb_relay_device_info *device_info); -/* Close a USB relay device*/ +/* Close a USB relay device */ void USBRL_API usb_relay_device_close(intptr_t hHandle); /** Turn ON a relay channel on the USB-Relay-Device @@ -106,7 +114,7 @@ int USBRL_API usb_relay_device_close_one_relay_channel(intptr_t hHandle, int ind */ int USBRL_API usb_relay_device_close_all_relay_channel(intptr_t hHandle); -/* +/** Get state of all channels of the USB-Relay-Device Status bits: one bit indicate a relay status. bit 0/1/2/3/4/5/6/7/8 indicate channel 1/2/3/4/5/6/7/8 status Bit value 1 means ON, 0 means OFF. @@ -114,6 +122,29 @@ Bit value 1 means ON, 0 means OFF. */ int USBRL_API usb_relay_device_get_status(intptr_t hHandle, unsigned int *status); +#if 1 /* added */ + +/** Get the library (dll) version +@return Lower 16 bits: the library version. Higher bits: undefined, ignore. +@note The original DLL does not have this function! +*/ +int USBRL_API usb_relay_device_lib_version(void); + + +/** + The following functions are for non-native callers, to avoid fumbling with C structs. + Native C/C++ callers do not need to use these. + The ptr_usb_relay_device_info arg is pointer to struct usb_relay_device_info, cast to intptr_t, void*, etc. +*/ + +/* Return next info struct pointer in the list returned by usb_relay_device_enumerate() */ +intptr_t USBRL_API usb_relay_device_next_dev(intptr_t ptr_usb_relay_device_info); +/* Get number of relay channels on the device */ +int USBRL_API usb_relay_device_get_num_relays(intptr_t ptr_usb_relay_device_info); +/* Get the ID string of the device. Returns pointer to const C string (1-byte, 0-terminated) */ +intptr_t USBRL_API usb_relay_device_get_id_string(intptr_t ptr_usb_relay_device_info); + +#endif /* added */ #ifdef __cplusplus } diff --git a/lib/usb_relay_lib.c b/lib/usb_relay_lib.c index abfd9f3..40e7bfa 100644 --- a/lib/usb_relay_lib.c +++ b/lib/usb_relay_lib.c @@ -2,6 +2,11 @@ * USB HID relays API library * http://git.io/bGcxrQ * +* This is reconstruction of the original Windows DLL, +* as supplied by the USB relay vendors. +* It is binary compatible and works with their example programs. +* The original usb_relay_device.h file has been slightly hacked up. +* * 12-jan-2015 pa01 Win32 version */ @@ -11,11 +16,13 @@ // Windows 32 or 64 bit #include "targetver.h" -#define WIN32_EXTRALEAN // Exclude rarely-used stuff from Windows headers +#define WIN32_EXTRALEAN #include -#define USBRL_API __declspec(dllexport) -#define USBRL_CALL _cdecl +/* The original DLL has cdecl calling convention */ +#define USBRL_CALL __cdecl +#define USBRL_API __declspec(dllexport) USBRL_CALL + #define snprintf _snprintf #endif //WIN32 @@ -545,13 +552,47 @@ int USBRL_API usb_relay_device_get_status(intptr_t hHandle, unsigned int *status return 0; } -/** Return lib version +/************ Added ****************/ + +/** Get the library (dll) version +@return Lower 16 bits: the library version. Higher bits: undefined, ignore. +@note The original DLL does not have this function! */ int USBRL_API usb_relay_device_lib_version(void) { return (int)(MY_VERSION); } +/** +The following functions are for non-native callers, to avoid fumbling with C structs. +Native C/C++ callers do not need to use these. +The ptr_usb_relay_device_info arg is pointer to struct usb_relay_device_info, cast to intptr_t, void*, etc. +*/ + +/* Return next info struct pointer in the list returned by usb_relay_device_enumerate() */ +intptr_t USBRL_API usb_relay_device_next_dev(intptr_t ptr_usb_relay_device_info) +{ + if (!ptr_usb_relay_device_info) + return 0; + return (intptr_t)(void*)((pusb_relay_device_info_t)ptr_usb_relay_device_info)->next; +} + +/* Get number of relay channels on the device */ +int USBRL_API usb_relay_device_get_num_relays(intptr_t ptr_usb_relay_device_info) +{ + if (!ptr_usb_relay_device_info) + return 0; + return (int)((pusb_relay_device_info_t)ptr_usb_relay_device_info)->type; +} + +/* Get the ID string of the device. Returns pointer to const C string (1-byte, 0-terminated) */ +intptr_t USBRL_API usb_relay_device_get_id_string(intptr_t ptr_usb_relay_device_info) +{ + if (!ptr_usb_relay_device_info) + return 0; + return (intptr_t)(void const *)((pusb_relay_device_info_t)ptr_usb_relay_device_info)->serial_number; +} + #ifdef __cplusplus } #endif -- 2.25.1