On Fri, Dec 18, 2015 at 2:41 AM,  <jf...@ms4.hinet.net> wrote:
> ValueError: Procedure probably called with too many arguments (4 bytes in 
> excess

The function's calling convention is x86 cdecl (CDLL, caller stack
cleanup), but you're using the x86 stdcall convention (WinDLL, callee
stack cleanup). For a 64-bit process they're actually the same, but
you're using 32-bit Python, so you have to pay attention to the
convention.

> _lib = windll.LoadLibrary("C:\\Windows\\System32\\libusb0.dll")

It should simply be

    _lib = CDLL('libusb0')

windll/WinDLL is the wrong calling convention. Everything else is just
a waste of keystrokes. windll.LoadLibrary is an inferior way to call
WinDLL, since it can't pass constructor arguments such as use_errno or
use_last_error. The System32 directory is on the DLL search path, and
Windows will add the .dll extension for you.

The calling convention is declared in the header file lusb0_usb.h [1].
For example:

    struct usb_bus *usb_get_busses(void);

Notice there's no mention of __stdcall there, so it's using the
default cdecl convention.

> _usb_dev_handle = c_void_p

You'll be better off using

    class _usb_dev_handle(Structure):
        pass

    _usb_dev_handle_p = POINTER(_usb_dev_handle)

This provides stronger type safety. c_void_p is too permissive. It's
easier to debug a ctypes ArgumentError than a memory access violation
or data corruption.

[1]: 
http://sourceforge.net/p/libusb-win32/code/413/tree/trunk/libusb/src/lusb0_usb.h
-- 
https://mail.python.org/mailman/listinfo/python-list

Reply via email to