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.
-
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 ctypesfrom ctypes import c_uint32, c_uint64, c_ushort, c_ubyte, c_double, c_void_p, Structure, POINTERimport os# 1. Constant definitionsPUC_SUCCEEDED = 0PUC_DETECT_TARGET_GBE2 = 0x00000002PUC_DETECT_TARGET_UC1 = 0x00000001PUC_COLOR_MONO = 0PUC_COLOR_COLOR = 1PUC_MAX_DEVICE = 16PUC_Q_COUNT = 64# 2. Struct definitionsclass 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 functiondef 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 oncelib.PUC_Initialize.restype = c_uint32lib.PUC_DetectDevice2.argtypes = [POINTER(PUC_DETECT_FILTER), POINTER(PUC_DETECT_INFO)]lib.PUC_DetectDevice2.restype = c_uint32lib.PUC_OpenDevice2.argtypes = [c_uint32, POINTER(c_void_p)]lib.PUC_OpenDevice2.restype = c_uint32lib.PUC_GetColorType.argtypes = [c_void_p, POINTER(c_uint32)]lib.PUC_GetColorType.restype = c_uint32lib.PUC_SetWhiteBalanceGain.argtypes = [c_double, c_double, c_double]lib.PUC_SetWhiteBalanceGain.restype = c_uint32lib.PUC_GetResolution.argtypes = [c_void_p, POINTER(c_uint32), POINTER(c_uint32)]lib.PUC_GetResolution.restype = c_uint32lib.PUC_SetResolution.argtypes = [c_void_p, c_uint32, c_uint32]lib.PUC_SetResolution.restype = c_uint32lib.PUC_SetFramerateShutter.argtypes = [c_void_p, c_uint32, c_uint32]lib.PUC_SetFramerateShutter.restype = c_uint32lib.PUC_SetSyncInMode.argtypes = [c_void_p, c_uint32, c_uint32]lib.PUC_SetSyncInMode.restype = c_uint32lib.PUC_GetQuantization2.argtypes = [c_void_p, POINTER(c_ushort)]lib.PUC_GetQuantization2.restype = c_uint32lib.PUC_GetXferDataSize.argtypes = [c_void_p, POINTER(c_uint32)]lib.PUC_GetXferDataSize.restype = c_uint32lib.PUC_GetSingleXferData.argtypes = [c_void_p, POINTER(PUC_XFER_DATA_INFO)]lib.PUC_GetSingleXferData.restype = c_uint32lib.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_uint32lib.PUC_DecodeDCData.argtypes = [POINTER(c_ubyte), c_uint32, c_uint32, c_uint32, c_uint32, POINTER(c_ubyte)]lib.PUC_DecodeDCData.restype = c_uint32lib.PUC_GetSerialNo.argtypes = [c_void_p, POINTER(c_uint64)]lib.PUC_GetSerialNo.restype = c_uint32lib.PUC_GetDeviceVersion.argtypes = [c_void_p, POINTER(c_uint32)]lib.PUC_GetDeviceVersion.restype = c_uint32lib.PUC_CloseDevice.argtypes = [c_void_p]lib.PUC_CloseDevice.restype = c_uint32return lib -
Create the HelloWorld script (
hello_world.py)In the same working folder, create
hello_world.pyand write the following code, which callspuclib.pyto test the device connection.hello_world.py from ctypes import c_uint32, c_uint64, c_void_p, byreffrom 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 SDKpuclib = 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 networkdetect_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}")returnprint(f"Detected a GbE-2 camera. (Devices found: {detect_info.nDeviceCount})")# 3. Open the first detected deviceh_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}")returnprint("SUCCESS: GbE-2 opened successfully!")# 4. Retrieve camera informationserial_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 devicepuclib.PUC_CloseDevice(h_device)if __name__ == "__main__":main() -
Run the script
Run it from a terminal (or command prompt).
Terminal window python hello_world.pyIf the serial number and device version are displayed on the console, it completed successfully.
Key Points of Modularization
Section titled “Key Points of Modularization”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.
2. Use in later sample code
Section titled “2. Use in later sample code”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.
