Skip to content
⚡ Developer documentation for INFINICAM, the real-time high-speed camera (UC-1.1 / GbE-2)

Creating the Common Module

When calling puclib.dll from Python’s ctypes module, common processing such as DLL loading and C struct/type definitions is modularized as puclib.py. All subsequent Python sample programs assume that they import the puclib.py created on this page.

  1. Create the common wrapper module (puclib.py)

    Create puclib.py, which gathers the constants, structs, and SDK initialization logic reused by each script, and place it in your working folder.

    puclib.py
    import ctypes
    from ctypes import c_uint32, c_uint64, c_ushort, c_ubyte, c_double, c_void_p, Structure, POINTER
    import os
    # 1. Constant definitions
    PUC_SUCCEEDED = 0
    PUC_DETECT_TARGET_GBE2 = 0x00000002
    PUC_DETECT_TARGET_UC1 = 0x00000001
    PUC_COLOR_MONO = 0
    PUC_COLOR_COLOR = 1
    PUC_MAX_DEVICE = 16
    PUC_Q_COUNT = 64
    # 2. Struct definitions
    class PUC_DETECT_FILTER(Structure):
    _fields_ = [
    ("nDeviceTypeFlags", c_uint32),
    ("nAdapterIPAddress", c_uint32),
    ("nTargetIPAddress", c_uint32),
    ("nDetectMode", c_uint32),
    ("nReserved", c_uint32 * 4),
    ]
    class PUC_DETECT_INFO(Structure):
    _fields_ = [
    ("nDeviceCount", c_uint32),
    ("nDeviceNoList", c_uint32 * PUC_MAX_DEVICE),
    ("nDeviceType", c_uint32 * PUC_MAX_DEVICE),
    ("nDeviceIPAddress", c_uint32 * PUC_MAX_DEVICE),
    ]
    class PUC_XFER_DATA_INFO(Structure):
    _fields_ = [
    ("pData", POINTER(c_ubyte)),
    ("nDataSize", c_uint32),
    ("nSequenceNo", ctypes.c_uint16),
    ("isDamaged", c_ubyte),
    ]
    # 3. DLL loading and API type setup function
    def load_sdk(dll_path=r"C:\infinicam_sdk\bin\x64\puclib.dll"):
    if not os.path.exists(dll_path):
    raise FileNotFoundError(f"Error: DLL not found at the specified path: {dll_path}")
    lib = ctypes.WinDLL(dll_path)
    # Set the argument and return types for all functions at once
    lib.PUC_Initialize.restype = c_uint32
    lib.PUC_DetectDevice2.argtypes = [POINTER(PUC_DETECT_FILTER), POINTER(PUC_DETECT_INFO)]
    lib.PUC_DetectDevice2.restype = c_uint32
    lib.PUC_OpenDevice2.argtypes = [c_uint32, POINTER(c_void_p)]
    lib.PUC_OpenDevice2.restype = c_uint32
    lib.PUC_GetColorType.argtypes = [c_void_p, POINTER(c_uint32)]
    lib.PUC_GetColorType.restype = c_uint32
    lib.PUC_SetWhiteBalanceGain.argtypes = [c_double, c_double, c_double]
    lib.PUC_SetWhiteBalanceGain.restype = c_uint32
    lib.PUC_GetResolution.argtypes = [c_void_p, POINTER(c_uint32), POINTER(c_uint32)]
    lib.PUC_GetResolution.restype = c_uint32
    lib.PUC_SetResolution.argtypes = [c_void_p, c_uint32, c_uint32]
    lib.PUC_SetResolution.restype = c_uint32
    lib.PUC_SetFramerateShutter.argtypes = [c_void_p, c_uint32, c_uint32]
    lib.PUC_SetFramerateShutter.restype = c_uint32
    lib.PUC_SetSyncInMode.argtypes = [c_void_p, c_uint32, c_uint32]
    lib.PUC_SetSyncInMode.restype = c_uint32
    lib.PUC_GetQuantization2.argtypes = [c_void_p, POINTER(c_ushort)]
    lib.PUC_GetQuantization2.restype = c_uint32
    lib.PUC_GetXferDataSize.argtypes = [c_void_p, POINTER(c_uint32)]
    lib.PUC_GetXferDataSize.restype = c_uint32
    lib.PUC_GetSingleXferData.argtypes = [c_void_p, POINTER(PUC_XFER_DATA_INFO)]
    lib.PUC_GetSingleXferData.restype = c_uint32
    lib.PUC_DecodeData.argtypes = [
    POINTER(c_ubyte), c_uint32, c_uint32, c_uint32, c_uint32, c_uint32, POINTER(c_ubyte), POINTER(c_ushort)
    ]
    lib.PUC_DecodeData.restype = c_uint32
    lib.PUC_DecodeDCData.argtypes = [
    POINTER(c_ubyte), c_uint32, c_uint32, c_uint32, c_uint32, POINTER(c_ubyte)
    ]
    lib.PUC_DecodeDCData.restype = c_uint32
    lib.PUC_GetSerialNo.argtypes = [c_void_p, POINTER(c_uint64)]
    lib.PUC_GetSerialNo.restype = c_uint32
    lib.PUC_GetDeviceVersion.argtypes = [c_void_p, POINTER(c_uint32)]
    lib.PUC_GetDeviceVersion.restype = c_uint32
    lib.PUC_CloseDevice.argtypes = [c_void_p]
    lib.PUC_CloseDevice.restype = c_uint32
    return lib
  2. Create the HelloWorld script (hello_world.py)

    In the same working folder, create hello_world.py and write the following code, which calls puclib.py to test the device connection.

    hello_world.py
    from ctypes import c_uint32, c_uint64, c_void_p, byref
    from puclib import (
    load_sdk, PUC_SUCCEEDED, PUC_DETECT_TARGET_GBE2,
    PUC_DETECT_FILTER, PUC_DETECT_INFO
    )
    def main():
    print("Initializing INFINICAM GbE-2 (Python)...")
    # 1. Load and initialize the SDK
    puclib = load_sdk()
    ret = puclib.PUC_Initialize()
    if ret != PUC_SUCCEEDED:
    print(f"Error: Failed to initialize the SDK. ErrorCode: {ret}")
    return
    # 2. Search for a GbE-2 device on the network
    detect_filter = PUC_DETECT_FILTER(nDeviceTypeFlags=PUC_DETECT_TARGET_GBE2)
    detect_info = PUC_DETECT_INFO()
    ret = puclib.PUC_DetectDevice2(byref(detect_filter), byref(detect_info))
    if ret != PUC_SUCCEEDED or detect_info.nDeviceCount == 0:
    print(f"Error: No GbE-2 camera was found. ErrorCode: {ret}")
    return
    print(f"Detected a GbE-2 camera. (Devices found: {detect_info.nDeviceCount})")
    # 3. Open the first detected device
    h_device = c_void_p()
    ret = puclib.PUC_OpenDevice2(0, byref(h_device))
    if ret != PUC_SUCCEEDED:
    print(f"Error: Failed to open the device. ErrorCode: {ret}")
    return
    print("SUCCESS: GbE-2 opened successfully!")
    # 4. Retrieve camera information
    serial_no = c_uint64()
    if puclib.PUC_GetSerialNo(h_device, byref(serial_no)) == PUC_SUCCEEDED:
    print(f"Serial number: {serial_no.value}")
    version = c_uint32()
    if puclib.PUC_GetDeviceVersion(h_device, byref(version)) == PUC_SUCCEEDED:
    print(f"Device version: {version.value}")
    # 5. Close the device
    puclib.PUC_CloseDevice(h_device)
    if __name__ == "__main__":
    main()
  3. Run the script

    Run it from a terminal (or command prompt).

    Terminal window
    python hello_world.py

    If the serial number and device version are displayed on the console, it completed successfully.


1. Consolidating repetitive type definitions

Section titled “1. Consolidating repetitive type definitions”

By defining structs such as PUC_DETECT_FILTER and load_sdk() in puclib.py, each feature script no longer needs to write out dozens of lines of argtypes / restype declarations every time.

From this point on, every Python sample (single_image.mdx, the various library-integration samples, etc.) starts by running from puclib import ... to operate the SDK.