1. PIXCI® Frame Grabbers: Using the XCLIB Python Wrapper

Python scripts can gain control of PIXCI® frame grabbers and access image data via the XCLIB C/C++ SDK/Library (.so file), a Python XCLIB module (.py file), and a wrapper (.so file) connecting them.

A Python script to snap and save an image can be as simple as:

    import xclib
    xclib.pxd_PIXCIopen("", "", "videosetup.fmt")
    xclib.pxd_doSnap(1, 1, 0);
    xclib.pxd_saveTiff(1, "saved.tif", 1, 0, 0, -1, -1, 0, 0)
    xclib.pxd_PIXCIclose();
although a few additions to check for errors are encouraged.


Linux Installation

The XCLIB C/C++ library, such as:

    xclib_x86_64.so             (XCLIB)
    xclib_i386.so               (XCLIB)
    xclib_aarch64.so            (XCLIB)
    xclib_armv7l.so             (XCLIB)
    xclyb_x86_64.so             (XCLIB-Lite)
    xclyb_i386.so               (XCLIB-Lite)
    xclyb_aarch64.so            (XCLIB-Lite)
    xclyb_armv7l.so             (XCLIB-Lite)
should be copied to /usr/lib, or other location as specified by ''LD_LIBRARY_PATH''. See Linux documentation regarding searches for shared libraries and ''LD_LIBRARY_PATH''.

The corresponding XCLIB Python wrapper, such as:

    xclib_py_wrap_x86_64.so     (XCLIB)
    xclib_py_wrap_i386.so       (XCLIB)
    xclib_py_wrap_aarch64.so    (XCLIB)
    xclib_py_wrap_armv7l.so     (XCLIB)
    xclyb_py_wrap_x86_64.so     (XCLIB-Lite)
    xclyb_py_wrap_i386.so       (XCLIB-Lite)
    xclyb_py_wrap_aarch64.so    (XCLIB-Lite)
    xclyb_py_wrap_armv7l.so     (XCLIB-Lite)
should copied to the same directory as the Python script, but as file name _xclib.so.

The corresponding XCLIB Python module:

    xclib_x86_64.py             (XCLIB)
    xclib_i386.py               (XCLIB)
    xclib_aarch64.py            (XCLIB)
    xclib_armv7l.py             (XCLIB)
    xclyb_x86_64.py             (XCLIB-Lite)
    xclyb_i386.py               (XCLIB-Lite)
    xclyb_aarch64.py            (XCLIB-Lite)
    xclyb_armv7l.py             (XCLIB-Lite)
should copied to the same directory as the Python script, but as file name xclib.py.


Windows Installation

The XCLIB C/C++ library, such as:

    XCLIBW64.DLL            (XCLIB)
    XCLIBW32.DLL            (XCLIB)
    XCLYBW64.DLL            (XCLIB-Lite)
    XCLYBW32.DLL            (XCLIB-Lite)
should be copied to c:\windows\system32, or to the same directory as the Python script.

The corresponding XCLIB Python wrapper, such as:

    XCLIB_PY_WRAP_W64.DLL   (XCLIB)
    XCLIB_PY_WRAP_W32.DLL   (XCLIB)
    XCLYB_PY_WRAP_W64.DLL   (XCLIB-Lite)
    XCLYB_PY_WRAP_W32.DLL   (XCLIB-Lite)
should copied to the same directory as the Python script, but as file name _xclib.pyd (the lower case file name is required by Python).

The corresponding XCLIB Python module:

    XCLIB_W64.PY            (XCLIB)
    XCLIB_W32.PY            (XCLIB)
    XCLYB_W64.PY            (XCLIB-Lite)
    XCLYB_W32.PY            (XCLIB-Lite)
should copied to the same directory as the Python script, but as file name xclib.py (the lower case file name is required by Python).


Function Differences

Several XCLIB functions pass pixel data or serial data using a ''char'', ''uchar'', or ''ushort'' array along with a cnt or bufsize array dimension, such as:

    pxd_serialRead(int unitmap, int rsvd0, char buf[], int cnt);
or
    pxd_readuchar(int unitmap,pxbuffer_t framebuf,
                  pxcoord_t ulx,pxcoord_t uly,pxcoord_t lrx,pxcoord_t lry,
                  uchar  *membuf,size_t cnt,const char *colorspace);
or
    pxd_mesgFaultText(int unitmap, char buf[], size_t bufsize);
    pxd_mesgErrorCode2(int err, char buf[], size_t bufsize)
Use the common Python:
    bytearray(...)
    array.array('b', ...)
    array.array('B', ...)
for ''uchar'' or ''char'' array parameters, use the common Python:
    array.array('H', ...)  # 'H' for 2 byte unsigned integer,
                           # Python implementation dependent
for ''ushort'' parameters. Do not pass the cnt or bufsize array dimension; it is implied from the Python array. Thus, one fewer parameter is coded via Python than described elsewhere.

For these functions, and of particular interest for reading or writing of voluminous pixel data, the wrapper makes use of the Python ''Buffer Protocol''; this avoids having the wrapper perform extra copying of data as it passes between Python and ''C''.

The XCLIB functions:

    pxd_serialRead(int unitmap, int rsvd0, char buf[], int cnt);
    pxd_serialWrite(int unitmap, int rsvd0, char buf[], int cnt);
allow use of a buf=NULL and/or cnt=0; in that mode they return the number of bytes available to be read, or the number of bytes that can be added to the write queue, respectively. Using:
    bytearray(0)
is suggested; regardless of whether the value of buf appears as a ''NULL'', the (implied) cnt will be 0.

The XCLIB functions pxd_infoSysTicksUnits, pxd_infoSysTicks, and pxd_buffersSysTicks2 pass values using an undimensioned ''uint32'' array without provision for a cnt array dimension, and are not supported via the XCLIB Python wrapper. Use alternate XCLIB function:

    double  pxd_infoSysTicksUnits2()
which returns a floating point value. Use alternate XCLIB functions:
    int     pxd_infoSysTicks2(uint32 ticks[2], size_t cnt)
    int     pxd_buffersSysTicks3(int unitmap, pxbuffer_t buffer,
                                 uint32 ticks[2], size_t cnt)
along with a common Python:
    array.array('L' ...)   # 'L' for 4 byte unsigned integer,
                           # Python implementation dependent
array. Do not pass the cnt array dimension.

Several XCLIB functions use a ''double'' array parameter, such as

    double gains[4]
for passing a set of values to, or from, the XCLIB function. Use the XCLIB wrapper specific ''doubleArray'', such as:
    gains = xclib.doubleArray(4)
    pxd_getAdcGainsA(1, gains)
    print(gains[0])
    ...
    print(gains[3])
As always, when invoking C/C++ functions with an array parameter, an array smaller than that expected by the function may result in faults and/or crashes; Python will not detect or prevent such misuse.

Several XCLIB functions use a string parameter, i.e. ''const char *'', for a file path name or color space specification. A Python string can be passed and will be converted to ''utf‑8'' encoding; an explicit:

    "camera.fmt".encode('utf-8')
is not required when using the XCLIB Python wrapper.

Deprecated XCLIB functions:

    pxd_SV2112_*
    pxd_SV1310_*
    pxd_SV1281_*
    pxd_SV9M001_*
    pxd_SV642_*
    pxd_SV643_*
are not supported via the XCLIB Python wrapper; use the newer:
    pxd_SILICONVIDEO_*
functions.


Examples

The xclibel1.py and xclibex1.py example scripts are provided with XCLIB.


Support

The XCLIB Python module and wrapper was developed and tested with Python 3 which has support for the Python ''Buffer Protocol''. Earlier versions of Python are neither tested nor will be supported.

The ''structured'' XCLIB functions are not currently supported via the XCLIB Python wrapper.

Use of the PXIPL library with the XCLIB Python module and wrapper is not currently supported.


Alternatives

The XCLIB Python module and wrapper was created using ''SWIG'' (Simple Wrapper and Interface Generator) along with XCLIB's .h files.

The Python community offers other tools and methods for developers to use, such as ''ctypes'', ''SIP'', and others.

Of particular note, the Python ''ctypes'' module may allow interfacing to XCLIB with a smaller code ''footprint''. Note that any any strings passed from Python (using Unicode) to XCLIB (using ASCII) using ''ctypes'' must be explicitly converted, for example with:

    "camera.fmt".encode('utf-8')

Copyright (C) EPIX, Inc. All Rights Reserved

Updated: 07-Aug-2025