python ctypes issue on different OSes

In 99% of the cases, inconsistencies between arguments (and / or return) type inconsistencies are the cause (check [SO]: C function called from Python via ctypes returns incorrect value (@CristiFati’s answer) for more details).

Always have [Python 3.Docs]: ctypes – A foreign function library for Python open when working with ctypes.

I found [GitHub]: erikssm/futronics-fingerprint-reader – (master) futronics-fingerprint-reader/ftrScanAPI.h (I don’t know how different it’s from what you currently have, but things you posted so far seem to match), and I did some changes to your code:

  • Define argtypes and restype for functions
  • Define missing types (for clarity only)
  • Some other insignificant changes (renames)
  • One other thing that I noticed in the above file, is a #pragma pack(push, 1) macro (check [MS.Docs]: pack for more details). For this structure it makes no difference (thanks @AnttiHaapala for the hint), as the 3 int (4 byte) members alignment doesn’t change, but for other structures (with “smaller” member types (e.g. char, short)) you might want to add: _pack_ = 1

Your modified code (needless to say, I didn’t run it as I don’t have the .dll):

from ctypes import wintypes

# ...

lib = ctypes.WinDLL('ftrScanAPI.dll') # provided by fingerprint scanner
class FTRSCAN_IMAGE_SIZE(ctypes.Structure):
    # _pack_ = 1
    _fields_ = [
        ("nWidth", ctypes.c_int),
        ("nHeight", ctypes.c_int),
        ("nImageSize", ctypes.c_int),
    ]

PFTRSCAN_IMAGE_SIZE = ctypes.POINTER(FTRSCAN_IMAGE_SIZE)
FTRHANDLE = ctypes.c_void_p

print('Open device and get device handle...')

lib.ftrScanOpenDevice.argtypes = []
lib.ftrScanOpenDevice.restype = FTRHANDLE

h_device = lib.ftrScanOpenDevice()
print('handle is', h_device)
print('Get image size...')
image_size = FTRSCAN_IMAGE_SIZE(0, 0, 0)

lib.ftrScanGetImageSize.argtypes = [FTRHANDLE, PFTRSCAN_IMAGE_SIZE]
lib.ftrScanGetImageSize.restype = wintypes.BOOL

if lib.ftrScanGetImageSize(h_device, ctypes.byref(image_size)):
    print('Get image size succeed...')
    print('  W', image_size.nWidth)
    print('  H', image_size.nHeight)
    print('  Size', image_size.nImageSize)
else:
    print('Get image size failed...')

Leave a Comment