From 29f9f9e3af3340df6a955881a93caf9d2a6d08d6 Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Fri, 13 Aug 2010 11:59:49 +0100 Subject: Introduced calling convention (for Windows) Under Windows, a variety of compilers and configurations are available, meaning that the manner of parameter passing (e.g. registers vs stack) can vary. Match the Windows API calling convention and document this appropriately. This calling convention will be used regardless of the configuration of the user's development platform. The only user-level complication is that all functions used as libusb callbacks must use the same calling convention as libusb. The LIBUSB_CALL macro is provided to make this easy. Signed-off-by: Michael Plante Signed-off-by: Pete Batard [dsd: slight change of strategy, add documentation] --- configure.ac | 4 +- doc/doxygen.cfg.in | 2 +- examples/dpfp.c | 6 +- examples/dpfp_threaded.c | 6 +- libusb/core.c | 57 ++++++++------- libusb/descriptor.c | 12 +-- libusb/io.c | 41 ++++++----- libusb/libusb.h | 185 ++++++++++++++++++++++++++++++----------------- libusb/libusbi.h | 9 +++ libusb/sync.c | 10 +-- 10 files changed, 202 insertions(+), 130 deletions(-) diff --git a/configure.ac b/configure.ac index 3c959e4..39b11f2 100644 --- a/configure.ac +++ b/configure.ac @@ -151,9 +151,9 @@ saved_cflags="$CFLAGS" CFLAGS="$CFLAGS -Werror -fvisibility=hidden" AC_COMPILE_IFELSE(AC_LANG_PROGRAM([]), [VISIBILITY_CFLAGS="-fvisibility=hidden" - AC_DEFINE([API_EXPORTED], [__attribute__((visibility("default")))], [Default visibility]) ], + AC_DEFINE([DEFAULT_VISIBILITY], [__attribute__((visibility("default")))], [Default visibility]) ], [ VISIBILITY_CFLAGS="" - AC_DEFINE([API_EXPORTED], [], [Default visibility]) ], + AC_DEFINE([DEFAULT_VISIBILITY], [], [Default visibility]) ], ]) CFLAGS="$saved_cflags" diff --git a/doc/doxygen.cfg.in b/doc/doxygen.cfg.in index 574b52f..128e1de 100644 --- a/doc/doxygen.cfg.in +++ b/doc/doxygen.cfg.in @@ -1054,7 +1054,7 @@ INCLUDE_FILE_PATTERNS = # undefined via #undef or recursively expanded use the := operator # instead of the = operator. -PREDEFINED = API_EXPORTED= +PREDEFINED = API_EXPORTED= LIBUSB_CALL= DEFAULT_VISIBILITY= # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. diff --git a/examples/dpfp.c b/examples/dpfp.c index 1970f10..af51e0f 100644 --- a/examples/dpfp.c +++ b/examples/dpfp.c @@ -149,7 +149,7 @@ static int set_mode(unsigned char data) return 0; } -static void cb_mode_changed(struct libusb_transfer *transfer) +static void LIBUSB_CALL cb_mode_changed(struct libusb_transfer *transfer) { if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { fprintf(stderr, "mode change transfer not completed!\n"); @@ -276,7 +276,7 @@ static int next_state(void) return 0; } -static void cb_irq(struct libusb_transfer *transfer) +static void LIBUSB_CALL cb_irq(struct libusb_transfer *transfer) { unsigned char irqtype = transfer->buffer[0]; @@ -315,7 +315,7 @@ static void cb_irq(struct libusb_transfer *transfer) do_exit = 2; } -static void cb_img(struct libusb_transfer *transfer) +static void LIBUSB_CALL cb_img(struct libusb_transfer *transfer) { if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { fprintf(stderr, "img transfer status %d?\n", transfer->status); diff --git a/examples/dpfp_threaded.c b/examples/dpfp_threaded.c index c6a0a60..4641a50 100644 --- a/examples/dpfp_threaded.c +++ b/examples/dpfp_threaded.c @@ -178,7 +178,7 @@ static int set_mode(unsigned char data) return 0; } -static void cb_mode_changed(struct libusb_transfer *transfer) +static void LIBUSB_CALL cb_mode_changed(struct libusb_transfer *transfer) { if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { fprintf(stderr, "mode change transfer not completed!\n"); @@ -305,7 +305,7 @@ static int next_state(void) return 0; } -static void cb_irq(struct libusb_transfer *transfer) +static void LIBUSB_CALL cb_irq(struct libusb_transfer *transfer) { unsigned char irqtype = transfer->buffer[0]; @@ -343,7 +343,7 @@ static void cb_irq(struct libusb_transfer *transfer) request_exit(2); } -static void cb_img(struct libusb_transfer *transfer) +static void LIBUSB_CALL cb_img(struct libusb_transfer *transfer) { if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { fprintf(stderr, "img transfer status %d?\n", transfer->status); diff --git a/libusb/core.c b/libusb/core.c index d9f76c8..623e1ac 100644 --- a/libusb/core.c +++ b/libusb/core.c @@ -598,7 +598,7 @@ struct libusb_device *usbi_get_device_by_session_id(struct libusb_context *ctx, * \returns the number of devices in the outputted list, or LIBUSB_ERROR_NO_MEM * on memory allocation failure. */ -API_EXPORTED ssize_t libusb_get_device_list(libusb_context *ctx, +ssize_t API_EXPORTED libusb_get_device_list(libusb_context *ctx, libusb_device ***list) { struct discovered_devs *discdevs = discovered_devs_alloc(); @@ -644,7 +644,7 @@ out: * \param list the list to free * \param unref_devices whether to unref the devices in the list */ -API_EXPORTED void libusb_free_device_list(libusb_device **list, +void API_EXPORTED libusb_free_device_list(libusb_device **list, int unref_devices) { if (!list) @@ -665,7 +665,7 @@ API_EXPORTED void libusb_free_device_list(libusb_device **list, * \param dev a device * \returns the bus number */ -API_EXPORTED uint8_t libusb_get_bus_number(libusb_device *dev) +uint8_t API_EXPORTED libusb_get_bus_number(libusb_device *dev) { return dev->bus_number; } @@ -675,7 +675,7 @@ API_EXPORTED uint8_t libusb_get_bus_number(libusb_device *dev) * \param dev a device * \returns the device address */ -API_EXPORTED uint8_t libusb_get_device_address(libusb_device *dev) +uint8_t API_EXPORTED libusb_get_device_address(libusb_device *dev) { return dev->device_address; } @@ -721,7 +721,7 @@ static const struct libusb_endpoint_descriptor *find_endpoint( * \returns LIBUSB_ERROR_NOT_FOUND if the endpoint does not exist * \returns LIBUSB_ERROR_OTHER on other failure */ -API_EXPORTED int libusb_get_max_packet_size(libusb_device *dev, +int API_EXPORTED libusb_get_max_packet_size(libusb_device *dev, unsigned char endpoint) { struct libusb_config_descriptor *config; @@ -770,7 +770,7 @@ API_EXPORTED int libusb_get_max_packet_size(libusb_device *dev, * \returns LIBUSB_ERROR_NOT_FOUND if the endpoint does not exist * \returns LIBUSB_ERROR_OTHER on other failure */ -API_EXPORTED int libusb_get_max_iso_packet_size(libusb_device *dev, +int API_EXPORTED libusb_get_max_iso_packet_size(libusb_device *dev, unsigned char endpoint) { struct libusb_config_descriptor *config; @@ -806,7 +806,8 @@ API_EXPORTED int libusb_get_max_iso_packet_size(libusb_device *dev, * \param dev the device to reference * \returns the same device */ -API_EXPORTED libusb_device *libusb_ref_device(libusb_device *dev) +DEFAULT_VISIBILITY +libusb_device * LIBUSB_CALL libusb_ref_device(libusb_device *dev) { usbi_mutex_lock(&dev->lock); dev->refcnt++; @@ -819,7 +820,7 @@ API_EXPORTED libusb_device *libusb_ref_device(libusb_device *dev) * causes the reference count to reach zero, the device shall be destroyed. * \param dev the device to unreference */ -API_EXPORTED void libusb_unref_device(libusb_device *dev) +void API_EXPORTED libusb_unref_device(libusb_device *dev) { int refcnt; @@ -908,7 +909,8 @@ void usbi_fd_notification(struct libusb_context *ctx) * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected * \returns another LIBUSB_ERROR code on other failure */ -API_EXPORTED int libusb_open(libusb_device *dev, libusb_device_handle **handle) +int API_EXPORTED libusb_open(libusb_device *dev, + libusb_device_handle **handle) { struct libusb_context *ctx = DEVICE_CTX(dev); struct libusb_device_handle *_handle; @@ -970,7 +972,8 @@ API_EXPORTED int libusb_open(libusb_device *dev, libusb_device_handle **handle) * \param product_id the idProduct value to search for * \returns a handle for the first found device, or NULL on error or if the * device could not be found. */ -API_EXPORTED libusb_device_handle *libusb_open_device_with_vid_pid( +DEFAULT_VISIBILITY +libusb_device_handle * LIBUSB_CALL libusb_open_device_with_vid_pid( libusb_context *ctx, uint16_t vendor_id, uint16_t product_id) { struct libusb_device **devs; @@ -1029,7 +1032,7 @@ static void do_close(struct libusb_context *ctx, * * \param dev_handle the handle to close */ -API_EXPORTED void libusb_close(libusb_device_handle *dev_handle) +void API_EXPORTED libusb_close(libusb_device_handle *dev_handle) { struct libusb_context *ctx; unsigned char dummy = 1; @@ -1090,7 +1093,8 @@ API_EXPORTED void libusb_close(libusb_device_handle *dev_handle) * \param dev_handle a device handle * \returns the underlying device */ -API_EXPORTED libusb_device *libusb_get_device(libusb_device_handle *dev_handle) +DEFAULT_VISIBILITY +libusb_device * LIBUSB_CALL libusb_get_device(libusb_device_handle *dev_handle) { return dev_handle->dev; } @@ -1115,7 +1119,7 @@ API_EXPORTED libusb_device *libusb_get_device(libusb_device_handle *dev_handle) * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected * \returns another LIBUSB_ERROR code on other failure */ -API_EXPORTED int libusb_get_configuration(libusb_device_handle *dev, +int API_EXPORTED libusb_get_configuration(libusb_device_handle *dev, int *config) { int r = LIBUSB_ERROR_NOT_SUPPORTED; @@ -1184,7 +1188,7 @@ API_EXPORTED int libusb_get_configuration(libusb_device_handle *dev, * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected * \returns another LIBUSB_ERROR code on other failure */ -API_EXPORTED int libusb_set_configuration(libusb_device_handle *dev, +int API_EXPORTED libusb_set_configuration(libusb_device_handle *dev, int configuration) { usbi_dbg("configuration %d", configuration); @@ -1215,7 +1219,7 @@ API_EXPORTED int libusb_set_configuration(libusb_device_handle *dev, * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected * \returns a LIBUSB_ERROR code on other failure */ -API_EXPORTED int libusb_claim_interface(libusb_device_handle *dev, +int API_EXPORTED libusb_claim_interface(libusb_device_handle *dev, int interface_number) { int r = 0; @@ -1252,7 +1256,7 @@ out: * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected * \returns another LIBUSB_ERROR code on other failure */ -API_EXPORTED int libusb_release_interface(libusb_device_handle *dev, +int API_EXPORTED libusb_release_interface(libusb_device_handle *dev, int interface_number) { int r; @@ -1297,7 +1301,7 @@ out: * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected * \returns another LIBUSB_ERROR code on other failure */ -API_EXPORTED int libusb_set_interface_alt_setting(libusb_device_handle *dev, +int API_EXPORTED libusb_set_interface_alt_setting(libusb_device_handle *dev, int interface_number, int alternate_setting) { usbi_dbg("interface %d altsetting %d", @@ -1332,7 +1336,7 @@ API_EXPORTED int libusb_set_interface_alt_setting(libusb_device_handle *dev, * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected * \returns another LIBUSB_ERROR code on other failure */ -API_EXPORTED int libusb_clear_halt(libusb_device_handle *dev, +int API_EXPORTED libusb_clear_halt(libusb_device_handle *dev, unsigned char endpoint) { usbi_dbg("endpoint %x", endpoint); @@ -1358,7 +1362,7 @@ API_EXPORTED int libusb_clear_halt(libusb_device_handle *dev, * device has been disconnected * \returns another LIBUSB_ERROR code on other failure */ -API_EXPORTED int libusb_reset_device(libusb_device_handle *dev) +int API_EXPORTED libusb_reset_device(libusb_device_handle *dev) { usbi_dbg(""); return usbi_backend->reset_device(dev); @@ -1377,7 +1381,7 @@ API_EXPORTED int libusb_reset_device(libusb_device_handle *dev) * \returns another LIBUSB_ERROR code on other failure * \see libusb_detach_kernel_driver() */ -API_EXPORTED int libusb_kernel_driver_active(libusb_device_handle *dev, +int API_EXPORTED libusb_kernel_driver_active(libusb_device_handle *dev, int interface_number) { usbi_dbg("interface %d", interface_number); @@ -1400,7 +1404,7 @@ API_EXPORTED int libusb_kernel_driver_active(libusb_device_handle *dev, * \returns another LIBUSB_ERROR code on other failure * \see libusb_kernel_driver_active() */ -API_EXPORTED int libusb_detach_kernel_driver(libusb_device_handle *dev, +int API_EXPORTED libusb_detach_kernel_driver(libusb_device_handle *dev, int interface_number) { usbi_dbg("interface %d", interface_number); @@ -1425,7 +1429,7 @@ API_EXPORTED int libusb_detach_kernel_driver(libusb_device_handle *dev, * \returns another LIBUSB_ERROR code on other failure * \see libusb_kernel_driver_active() */ -API_EXPORTED int libusb_attach_kernel_driver(libusb_device_handle *dev, +int API_EXPORTED libusb_attach_kernel_driver(libusb_device_handle *dev, int interface_number) { usbi_dbg("interface %d", interface_number); @@ -1464,7 +1468,7 @@ API_EXPORTED int libusb_attach_kernel_driver(libusb_device_handle *dev, * \param ctx the context to operate on, or NULL for the default context * \param level debug level to set */ -API_EXPORTED void libusb_set_debug(libusb_context *ctx, int level) +void API_EXPORTED libusb_set_debug(libusb_context *ctx, int level) { USBI_GET_CONTEXT(ctx); if (!ctx->debug_fixed) @@ -1484,7 +1488,7 @@ API_EXPORTED void libusb_set_debug(libusb_context *ctx, int level) * \returns 0 on success, or a LIBUSB_ERROR code on failure * \see contexts */ -API_EXPORTED int libusb_init(libusb_context **context) +int API_EXPORTED libusb_init(libusb_context **context) { char *dbg = getenv("LIBUSB_DEBUG"); struct libusb_context *ctx; @@ -1558,7 +1562,7 @@ err_unlock: * before your application terminates. * \param ctx the context to deinitialize, or NULL for the default context */ -API_EXPORTED void libusb_exit(struct libusb_context *ctx) +void API_EXPORTED libusb_exit(struct libusb_context *ctx) { usbi_dbg(""); USBI_GET_CONTEXT(ctx); @@ -1660,7 +1664,8 @@ void usbi_log(struct libusb_context *ctx, enum usbi_log_level level, * \returns a short description of the error code in English, or NULL if the * error descriptions are unavailable */ -API_EXPORTED const char *libusb_strerror(enum libusb_error errcode) +DEFAULT_VISIBILITY +const char * LIBUSB_CALL libusb_strerror(enum libusb_error errcode) { switch (errcode) { case LIBUSB_SUCCESS: diff --git a/libusb/descriptor.c b/libusb/descriptor.c index 041c39d..54a47b4 100644 --- a/libusb/descriptor.c +++ b/libusb/descriptor.c @@ -430,7 +430,7 @@ err: * \param desc output location for the descriptor data * \returns 0 on success or a LIBUSB_ERROR code on failure */ -API_EXPORTED int libusb_get_device_descriptor(libusb_device *dev, +int API_EXPORTED libusb_get_device_descriptor(libusb_device *dev, struct libusb_device_descriptor *desc) { unsigned char raw_desc[DEVICE_DESC_LENGTH]; @@ -466,7 +466,7 @@ API_EXPORTED int libusb_get_device_descriptor(libusb_device *dev, * \returns another LIBUSB_ERROR code on error * \see libusb_get_config_descriptor */ -API_EXPORTED int libusb_get_active_config_descriptor(libusb_device *dev, +int API_EXPORTED libusb_get_active_config_descriptor(libusb_device *dev, struct libusb_config_descriptor **config) { struct libusb_config_descriptor *_config = malloc(sizeof(*_config)); @@ -531,7 +531,7 @@ err: * \see libusb_get_active_config_descriptor() * \see libusb_get_config_descriptor_by_value() */ -API_EXPORTED int libusb_get_config_descriptor(libusb_device *dev, +int API_EXPORTED libusb_get_config_descriptor(libusb_device *dev, uint8_t config_index, struct libusb_config_descriptor **config) { struct libusb_config_descriptor *_config; @@ -630,7 +630,7 @@ int usbi_get_config_index_by_value(struct libusb_device *dev, * \see libusb_get_active_config_descriptor() * \see libusb_get_config_descriptor() */ -API_EXPORTED int libusb_get_config_descriptor_by_value(libusb_device *dev, +int API_EXPORTED libusb_get_config_descriptor_by_value(libusb_device *dev, uint8_t bConfigurationValue, struct libusb_config_descriptor **config) { int idx; @@ -651,7 +651,7 @@ API_EXPORTED int libusb_get_config_descriptor_by_value(libusb_device *dev, * * \param config the configuration descriptor to free */ -API_EXPORTED void libusb_free_config_descriptor( +void API_EXPORTED libusb_free_config_descriptor( struct libusb_config_descriptor *config) { if (!config) @@ -673,7 +673,7 @@ API_EXPORTED void libusb_free_config_descriptor( * \param length size of data buffer * \returns number of bytes returned in data, or LIBUSB_ERROR code on failure */ -API_EXPORTED int libusb_get_string_descriptor_ascii(libusb_device_handle *dev, +int API_EXPORTED libusb_get_string_descriptor_ascii(libusb_device_handle *dev, uint8_t desc_index, unsigned char *data, int length) { unsigned char tbuf[255]; /* Some devices choke on size > 255 */ diff --git a/libusb/io.c b/libusb/io.c index 36f9244..2ea38a5 100644 --- a/libusb/io.c +++ b/libusb/io.c @@ -1177,7 +1177,9 @@ out: * \param iso_packets number of isochronous packet descriptors to allocate * \returns a newly allocated transfer, or NULL on error */ -API_EXPORTED struct libusb_transfer *libusb_alloc_transfer(int iso_packets) +DEFAULT_VISIBILITY +struct libusb_transfer * LIBUSB_CALL libusb_alloc_transfer( + int iso_packets) { size_t os_alloc_size = usbi_backend->transfer_priv_size + (usbi_backend->add_iso_packet_size * iso_packets); @@ -1212,7 +1214,7 @@ API_EXPORTED struct libusb_transfer *libusb_alloc_transfer(int iso_packets) * * \param transfer the transfer to free */ -API_EXPORTED void libusb_free_transfer(struct libusb_transfer *transfer) +void API_EXPORTED libusb_free_transfer(struct libusb_transfer *transfer) { struct usbi_transfer *itransfer; if (!transfer) @@ -1236,7 +1238,7 @@ API_EXPORTED void libusb_free_transfer(struct libusb_transfer *transfer) * \returns LIBUSB_ERROR_BUSY if the transfer has already been submitted. * \returns another LIBUSB_ERROR code on other failure */ -API_EXPORTED int libusb_submit_transfer(struct libusb_transfer *transfer) +int API_EXPORTED libusb_submit_transfer(struct libusb_transfer *transfer) { struct libusb_context *ctx = TRANSFER_CTX(transfer); struct usbi_transfer *itransfer = @@ -1292,7 +1294,7 @@ out: * cancelled. * \returns a LIBUSB_ERROR code on failure */ -API_EXPORTED int libusb_cancel_transfer(struct libusb_transfer *transfer) +int API_EXPORTED libusb_cancel_transfer(struct libusb_transfer *transfer) { struct usbi_transfer *itransfer = __LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer); @@ -1464,7 +1466,7 @@ int usbi_handle_transfer_cancellation(struct usbi_transfer *transfer) * \returns 1 if the lock was not obtained (i.e. another thread holds the lock) * \see \ref mtasync */ -API_EXPORTED int libusb_try_lock_events(libusb_context *ctx) +int API_EXPORTED libusb_try_lock_events(libusb_context *ctx) { int r; USBI_GET_CONTEXT(ctx); @@ -1505,7 +1507,7 @@ API_EXPORTED int libusb_try_lock_events(libusb_context *ctx) * \param ctx the context to operate on, or NULL for the default context * \see \ref mtasync */ -API_EXPORTED void libusb_lock_events(libusb_context *ctx) +void API_EXPORTED libusb_lock_events(libusb_context *ctx) { USBI_GET_CONTEXT(ctx); usbi_mutex_lock(&ctx->events_lock); @@ -1520,7 +1522,7 @@ API_EXPORTED void libusb_lock_events(libusb_context *ctx) * \param ctx the context to operate on, or NULL for the default context * \see \ref mtasync */ -API_EXPORTED void libusb_unlock_events(libusb_context *ctx) +void API_EXPORTED libusb_unlock_events(libusb_context *ctx) { USBI_GET_CONTEXT(ctx); ctx->event_handler_active = 0; @@ -1555,7 +1557,7 @@ API_EXPORTED void libusb_unlock_events(libusb_context *ctx) * \returns 0 if this thread must give up the events lock * \see \ref fullstory "Multi-threaded I/O: the full story" */ -API_EXPORTED int libusb_event_handling_ok(libusb_context *ctx) +int API_EXPORTED libusb_event_handling_ok(libusb_context *ctx) { int r; USBI_GET_CONTEXT(ctx); @@ -1583,7 +1585,7 @@ API_EXPORTED int libusb_event_handling_ok(libusb_context *ctx) * \returns 0 if there are no threads currently handling events * \see \ref mtasync */ -API_EXPORTED int libusb_event_handler_active(libusb_context *ctx) +int API_EXPORTED libusb_event_handler_active(libusb_context *ctx) { int r; USBI_GET_CONTEXT(ctx); @@ -1620,7 +1622,7 @@ API_EXPORTED int libusb_event_handler_active(libusb_context *ctx) * \param ctx the context to operate on, or NULL for the default context * \see \ref mtasync */ -API_EXPORTED void libusb_lock_event_waiters(libusb_context *ctx) +void API_EXPORTED libusb_lock_event_waiters(libusb_context *ctx) { USBI_GET_CONTEXT(ctx); usbi_mutex_lock(&ctx->event_waiters_lock); @@ -1631,7 +1633,7 @@ API_EXPORTED void libusb_lock_event_waiters(libusb_context *ctx) * \param ctx the context to operate on, or NULL for the default context * \see \ref mtasync */ -API_EXPORTED void libusb_unlock_event_waiters(libusb_context *ctx) +void API_EXPORTED libusb_unlock_event_waiters(libusb_context *ctx) { USBI_GET_CONTEXT(ctx); usbi_mutex_unlock(&ctx->event_waiters_lock); @@ -1662,7 +1664,7 @@ API_EXPORTED void libusb_unlock_event_waiters(libusb_context *ctx) * \returns 1 if the timeout expired * \see \ref mtasync */ -API_EXPORTED int libusb_wait_for_event(libusb_context *ctx, struct timeval *tv) +int API_EXPORTED libusb_wait_for_event(libusb_context *ctx, struct timeval *tv) { struct timespec timeout; int r; @@ -1942,7 +1944,7 @@ static int get_next_timeout(libusb_context *ctx, struct timeval *tv, * non-blocking mode * \returns 0 on success, or a LIBUSB_ERROR code on failure */ -API_EXPORTED int libusb_handle_events_timeout(libusb_context *ctx, +int API_EXPORTED libusb_handle_events_timeout(libusb_context *ctx, struct timeval *tv) { int r; @@ -1996,7 +1998,7 @@ retry: * \param ctx the context to operate on, or NULL for the default context * \returns 0 on success, or a LIBUSB_ERROR code on failure */ -API_EXPORTED int libusb_handle_events(libusb_context *ctx) +int API_EXPORTED libusb_handle_events(libusb_context *ctx) { struct timeval tv; tv.tv_sec = 60; @@ -2021,7 +2023,7 @@ API_EXPORTED int libusb_handle_events(libusb_context *ctx) * \returns 0 on success, or a LIBUSB_ERROR code on failure * \see \ref mtasync */ -API_EXPORTED int libusb_handle_events_locked(libusb_context *ctx, +int API_EXPORTED libusb_handle_events_locked(libusb_context *ctx, struct timeval *tv) { int r; @@ -2065,7 +2067,7 @@ API_EXPORTED int libusb_handle_events_locked(libusb_context *ctx, * or through regular activity on the file descriptors. * \see \ref pollmain "Polling libusb file descriptors for event handling" */ -API_EXPORTED int libusb_pollfds_handle_timeouts(libusb_context *ctx) +int API_EXPORTED libusb_pollfds_handle_timeouts(libusb_context *ctx) { #if defined(USBI_OS_HANDLES_TIMEOUT) return 1; @@ -2105,7 +2107,7 @@ API_EXPORTED int libusb_pollfds_handle_timeouts(libusb_context *ctx) * \returns 0 if there are no pending timeouts, 1 if a timeout was returned, * or LIBUSB_ERROR_OTHER on failure */ -API_EXPORTED int libusb_get_next_timeout(libusb_context *ctx, +int API_EXPORTED libusb_get_next_timeout(libusb_context *ctx, struct timeval *tv) { #ifndef USBI_OS_HANDLES_TIMEOUT @@ -2191,7 +2193,7 @@ API_EXPORTED int libusb_get_next_timeout(libusb_context *ctx, * \param user_data User data to be passed back to callbacks (useful for * passing context information) */ -API_EXPORTED void libusb_set_pollfd_notifiers(libusb_context *ctx, +void API_EXPORTED libusb_set_pollfd_notifiers(libusb_context *ctx, libusb_pollfd_added_cb added_cb, libusb_pollfd_removed_cb removed_cb, void *user_data) { @@ -2260,7 +2262,8 @@ void usbi_remove_pollfd(struct libusb_context *ctx, int fd) * \returns a NULL-terminated list of libusb_pollfd structures, or NULL on * error */ -API_EXPORTED const struct libusb_pollfd **libusb_get_pollfds( +DEFAULT_VISIBILITY +const struct libusb_pollfd ** LIBUSB_CALL libusb_get_pollfds( libusb_context *ctx) { struct libusb_pollfd **ret = NULL; diff --git a/libusb/libusb.h b/libusb/libusb.h index 4f91960..8dc3362 100644 --- a/libusb/libusb.h +++ b/libusb/libusb.h @@ -47,6 +47,44 @@ #endif #endif +/** \def LIBUSB_CALL + * \ingroup misc + * libusb's Windows calling convention. + * + * Under Windows, the selection of available compilers and configurations + * means that, unlike other platforms, there is not one true calling + * convention (calling convention: the manner in which parameters are + * passed to funcions in the generated assembly code). + * + * Matching the Windows API itself, libusb uses the WINAPI convention (which + * translates to the stdcall convention) and guarantees that the + * library is compiled in this way. The public header file also includes + * appropriate annotations so that your own software will use the right + * convention, even if another convention is being used by default within + * your codebase. + * + * The one consideration that you must apply in your software is to mark + * all functions which you use as libusb callbacks with this LIBUSB_CALL + * annotation, so that they too get compiled for the correct calling + * convention. + * + * On non-Windows operating systems, this macro is defined as nothing. This + * means that you can apply it to your code without worrying about + * cross-platform compatibility. + */ +/* LIBUSB_CALL must be defined on both definition and declaration of libusb + * functions. You'd think that declaration would be enough, but cygwin will + * complain about conflicting types unless both are marked this way. + * The placement of this macro is important too; it must appear after the + * return type, before the function name. See internal documentation for + * API_EXPORTED. + */ +#if defined(_WIN32) || defined(__CYGWIN__) +#define LIBUSB_CALL WINAPI +#else +#define LIBUSB_CALL +#endif + #ifdef __cplusplus extern "C" { #endif @@ -730,7 +768,7 @@ struct libusb_transfer; * \param transfer The libusb_transfer struct the callback function is being * notified about. */ -typedef void (*libusb_transfer_cb_fn)(struct libusb_transfer *transfer); +typedef void (LIBUSB_CALL *libusb_transfer_cb_fn)(struct libusb_transfer *transfer); /** \ingroup asyncio * The generic USB transfer structure. The user populates this structure and @@ -796,51 +834,63 @@ struct libusb_transfer { ; }; -int libusb_init(libusb_context **ctx); -void libusb_exit(libusb_context *ctx); -void libusb_set_debug(libusb_context *ctx, int level); -const char *libusb_strerror(enum libusb_error errcode); +int LIBUSB_CALL libusb_init(libusb_context **ctx); +void LIBUSB_CALL libusb_exit(libusb_context *ctx); +void LIBUSB_CALL libusb_set_debug(libusb_context *ctx, int level); +const char * LIBUSB_CALL libusb_strerror(enum libusb_error errcode); -ssize_t libusb_get_device_list(libusb_context *ctx, +ssize_t LIBUSB_CALL libusb_get_device_list(libusb_context *ctx, libusb_device ***list); -void libusb_free_device_list(libusb_device **list, int unref_devices); -libusb_device *libusb_ref_device(libusb_device *dev); -void libusb_unref_device(libusb_device *dev); - -int libusb_get_configuration(libusb_device_handle *dev, int *config); -int libusb_get_device_descriptor(libusb_device *dev, +void LIBUSB_CALL libusb_free_device_list(libusb_device **list, + int unref_devices); +libusb_device * LIBUSB_CALL libusb_ref_device(libusb_device *dev); +void LIBUSB_CALL libusb_unref_device(libusb_device *dev); + +int LIBUSB_CALL libusb_get_configuration(libusb_device_handle *dev, + int *config); +int LIBUSB_CALL libusb_get_device_descriptor(libusb_device *dev, struct libusb_device_descriptor *desc); -int libusb_get_active_config_descriptor(libusb_device *dev, +int LIBUSB_CALL libusb_get_active_config_descriptor(libusb_device *dev, struct libusb_config_descriptor **config); -int libusb_get_config_descriptor(libusb_device *dev, uint8_t config_index, - struct libusb_config_descriptor **config); -int libusb_get_config_descriptor_by_value(libusb_device *dev, +int LIBUSB_CALL libusb_get_config_descriptor(libusb_device *dev, + uint8_t config_index, struct libusb_config_descriptor **config); +int LIBUSB_CALL libusb_get_config_descriptor_by_value(libusb_device *dev, uint8_t bConfigurationValue, struct libusb_config_descriptor **config); -void libusb_free_config_descriptor(struct libusb_config_descriptor *config); -uint8_t libusb_get_bus_number(libusb_device *dev); -uint8_t libusb_get_device_address(libusb_device *dev); -int libusb_get_max_packet_size(libusb_device *dev, unsigned char endpoint); -int libusb_get_max_iso_packet_size(libusb_device *dev, unsigned char endpoint); - -int libusb_open(libusb_device *dev, libusb_device_handle **handle); -void libusb_close(libusb_device_handle *dev_handle); -libusb_device *libusb_get_device(libusb_device_handle *dev_handle); - -int libusb_set_configuration(libusb_device_handle *dev, int configuration); -int libusb_claim_interface(libusb_device_handle *dev, int interface_number); -int libusb_release_interface(libusb_device_handle *dev, int interface_number); - -libusb_device_handle *libusb_open_device_with_vid_pid(libusb_context *ctx, - uint16_t vendor_id, uint16_t product_id); - -int libusb_set_interface_alt_setting(libusb_device_handle *dev, +void LIBUSB_CALL libusb_free_config_descriptor( + struct libusb_config_descriptor *config); +uint8_t LIBUSB_CALL libusb_get_bus_number(libusb_device *dev); +uint8_t LIBUSB_CALL libusb_get_device_address(libusb_device *dev); +int LIBUSB_CALL libusb_get_max_packet_size(libusb_device *dev, + unsigned char endpoint); +int LIBUSB_CALL libusb_get_max_iso_packet_size(libusb_device *dev, + unsigned char endpoint); + +int LIBUSB_CALL libusb_open(libusb_device *dev, libusb_device_handle **handle); +void LIBUSB_CALL libusb_close(libusb_device_handle *dev_handle); +libusb_device * LIBUSB_CALL libusb_get_device(libusb_device_handle *dev_handle); + +int LIBUSB_CALL libusb_set_configuration(libusb_device_handle *dev, + int configuration); +int LIBUSB_CALL libusb_claim_interface(libusb_device_handle *dev, + int interface_number); +int LIBUSB_CALL libusb_release_interface(libusb_device_handle *dev, + int interface_number); + +libusb_device_handle * LIBUSB_CALL libusb_open_device_with_vid_pid( + libusb_context *ctx, uint16_t vendor_id, uint16_t product_id); + +int LIBUSB_CALL libusb_set_interface_alt_setting(libusb_device_handle *dev, int interface_number, int alternate_setting); -int libusb_clear_halt(libusb_device_handle *dev, unsigned char endpoint); -int libusb_reset_device(libusb_device_handle *dev); +int LIBUSB_CALL libusb_clear_halt(libusb_device_handle *dev, + unsigned char endpoint); +int LIBUSB_CALL libusb_reset_device(libusb_device_handle *dev); -int libusb_kernel_driver_active(libusb_device_handle *dev, int interface_number); -int libusb_detach_kernel_driver(libusb_device_handle *dev, int interface_number); -int libusb_attach_kernel_driver(libusb_device_handle *dev, int interface_number); +int LIBUSB_CALL libusb_kernel_driver_active(libusb_device_handle *dev, + int interface_number); +int LIBUSB_CALL libusb_detach_kernel_driver(libusb_device_handle *dev, + int interface_number); +int LIBUSB_CALL libusb_attach_kernel_driver(libusb_device_handle *dev, + int interface_number); /* async I/O */ @@ -914,10 +964,10 @@ static inline void libusb_fill_control_setup(unsigned char *buffer, setup->wLength = libusb_cpu_to_le16(wLength); } -struct libusb_transfer *libusb_alloc_transfer(int iso_packets); -int libusb_submit_transfer(struct libusb_transfer *transfer); -int libusb_cancel_transfer(struct libusb_transfer *transfer); -void libusb_free_transfer(struct libusb_transfer *transfer); +struct libusb_transfer * LIBUSB_CALL libusb_alloc_transfer(int iso_packets); +int LIBUSB_CALL libusb_submit_transfer(struct libusb_transfer *transfer); +int LIBUSB_CALL libusb_cancel_transfer(struct libusb_transfer *transfer); +void LIBUSB_CALL libusb_free_transfer(struct libusb_transfer *transfer); /** \ingroup asyncio * Helper function to populate the required \ref libusb_transfer fields @@ -1144,15 +1194,15 @@ static inline unsigned char *libusb_get_iso_packet_buffer_simple( /* sync I/O */ -int libusb_control_transfer(libusb_device_handle *dev_handle, +int LIBUSB_CALL libusb_control_transfer(libusb_device_handle *dev_handle, uint8_t request_type, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, unsigned char *data, uint16_t wLength, unsigned int timeout); -int libusb_bulk_transfer(libusb_device_handle *dev_handle, +int LIBUSB_CALL libusb_bulk_transfer(libusb_device_handle *dev_handle, unsigned char endpoint, unsigned char *data, int length, int *actual_length, unsigned int timeout); -int libusb_interrupt_transfer(libusb_device_handle *dev_handle, +int LIBUSB_CALL libusb_interrupt_transfer(libusb_device_handle *dev_handle, unsigned char endpoint, unsigned char *data, int length, int *actual_length, unsigned int timeout); @@ -1198,25 +1248,28 @@ static inline int libusb_get_string_descriptor(libusb_device_handle *dev, langid, data, (uint16_t) length, 1000); } -int libusb_get_string_descriptor_ascii(libusb_device_handle *dev, +int LIBUSB_CALL libusb_get_string_descriptor_ascii(libusb_device_handle *dev, uint8_t desc_index, unsigned char *data, int length); /* polling and timeouts */ -int libusb_try_lock_events(libusb_context *ctx); -void libusb_lock_events(libusb_context *ctx); -void libusb_unlock_events(libusb_context *ctx); -int libusb_event_handling_ok(libusb_context *ctx); -int libusb_event_handler_active(libusb_context *ctx); -void libusb_lock_event_waiters(libusb_context *ctx); -void libusb_unlock_event_waiters(libusb_context *ctx); -int libusb_wait_for_event(libusb_context *ctx, struct timeval *tv); - -int libusb_handle_events_timeout(libusb_context *ctx, struct timeval *tv); -int libusb_handle_events(libusb_context *ctx); -int libusb_handle_events_locked(libusb_context *ctx, struct timeval *tv); -int libusb_pollfds_handle_timeouts(libusb_context *ctx); -int libusb_get_next_timeout(libusb_context *ctx, struct timeval *tv); +int LIBUSB_CALL libusb_try_lock_events(libusb_context *ctx); +void LIBUSB_CALL libusb_lock_events(libusb_context *ctx); +void LIBUSB_CALL libusb_unlock_events(libusb_context *ctx); +int LIBUSB_CALL libusb_event_handling_ok(libusb_context *ctx); +int LIBUSB_CALL libusb_event_handler_active(libusb_context *ctx); +void LIBUSB_CALL libusb_lock_event_waiters(libusb_context *ctx); +void LIBUSB_CALL libusb_unlock_event_waiters(libusb_context *ctx); +int LIBUSB_CALL libusb_wait_for_event(libusb_context *ctx, struct timeval *tv); + +int LIBUSB_CALL libusb_handle_events_timeout(libusb_context *ctx, + struct timeval *tv); +int LIBUSB_CALL libusb_handle_events(libusb_context *ctx); +int LIBUSB_CALL libusb_handle_events_locked(libusb_context *ctx, + struct timeval *tv); +int LIBUSB_CALL libusb_pollfds_handle_timeouts(libusb_context *ctx); +int LIBUSB_CALL libusb_get_next_timeout(libusb_context *ctx, + struct timeval *tv); /** \ingroup poll * File descriptor for polling @@ -1242,7 +1295,8 @@ struct libusb_pollfd { * libusb_set_pollfd_notifiers() call * \see libusb_set_pollfd_notifiers() */ -typedef void (*libusb_pollfd_added_cb)(int fd, short events, void *user_data); +typedef void (LIBUSB_CALL *libusb_pollfd_added_cb)(int fd, short events, + void *user_data); /** \ingroup poll * Callback function, invoked when a file descriptor should be removed from @@ -1253,10 +1307,11 @@ typedef void (*libusb_pollfd_added_cb)(int fd, short events, void *user_data); * libusb_set_pollfd_notifiers() call * \see libusb_set_pollfd_notifiers() */ -typedef void (*libusb_pollfd_removed_cb)(int fd, void *user_data); +typedef void (LIBUSB_CALL *libusb_pollfd_removed_cb)(int fd, void *user_data); -const struct libusb_pollfd **libusb_get_pollfds(libusb_context *ctx); -void libusb_set_pollfd_notifiers(libusb_context *ctx, +const struct libusb_pollfd ** LIBUSB_CALL libusb_get_pollfds( + libusb_context *ctx); +void LIBUSB_CALL libusb_set_pollfd_notifiers(libusb_context *ctx, libusb_pollfd_added_cb added_cb, libusb_pollfd_removed_cb removed_cb, void *user_data); diff --git a/libusb/libusbi.h b/libusb/libusbi.h index 464caa1..9b2fa70 100644 --- a/libusb/libusbi.h +++ b/libusb/libusbi.h @@ -29,6 +29,15 @@ #include +/* Inside the libusb code, mark all public functions as follows: + * return_type API_EXPORTED function_name(params) { ... } + * But if the function returns a pointer, mark it as follows: + * DEFAULT_VISIBILITY return_type * LIBUSB_CALL function_name(params) { ... } + * In the libusb public header, mark all declarations as: + * return_type LIBUSB_CALL function_name(params); + */ +#define API_EXPORTED LIBUSB_CALL DEFAULT_VISIBILITY + #define DEVICE_DESC_LENGTH 18 #define USB_MAXENDPOINTS 32 diff --git a/libusb/sync.c b/libusb/sync.c index a978b47..3870f95 100644 --- a/libusb/sync.c +++ b/libusb/sync.c @@ -33,7 +33,7 @@ * may wish to consider using the \ref asyncio "asynchronous I/O API" instead. */ -static void ctrl_transfer_cb(struct libusb_transfer *transfer) +static void LIBUSB_CALL ctrl_transfer_cb(struct libusb_transfer *transfer) { int *completed = transfer->user_data; *completed = 1; @@ -69,7 +69,7 @@ static void ctrl_transfer_cb(struct libusb_transfer *transfer) * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected * \returns another LIBUSB_ERROR code on other failures */ -API_EXPORTED int libusb_control_transfer(libusb_device_handle *dev_handle, +int API_EXPORTED libusb_control_transfer(libusb_device_handle *dev_handle, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, unsigned char *data, uint16_t wLength, unsigned int timeout) { @@ -142,7 +142,7 @@ API_EXPORTED int libusb_control_transfer(libusb_device_handle *dev_handle, return r; } -static void bulk_transfer_cb(struct libusb_transfer *transfer) +static void LIBUSB_CALL bulk_transfer_cb(struct libusb_transfer *transfer) { int *completed = transfer->user_data; *completed = 1; @@ -252,7 +252,7 @@ static int do_sync_bulk_transfer(struct libusb_device_handle *dev_handle, * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected * \returns another LIBUSB_ERROR code on other failures */ -API_EXPORTED int libusb_bulk_transfer(struct libusb_device_handle *dev_handle, +int API_EXPORTED libusb_bulk_transfer(struct libusb_device_handle *dev_handle, unsigned char endpoint, unsigned char *data, int length, int *transferred, unsigned int timeout) { @@ -301,7 +301,7 @@ API_EXPORTED int libusb_bulk_transfer(struct libusb_device_handle *dev_handle, * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected * \returns another LIBUSB_ERROR code on other error */ -API_EXPORTED int libusb_interrupt_transfer( +int API_EXPORTED libusb_interrupt_transfer( struct libusb_device_handle *dev_handle, unsigned char endpoint, unsigned char *data, int length, int *transferred, unsigned int timeout) { -- cgit v1.2.3