Python is a programming language that has close relationship with C. Calling C functions from Python is straightforward via ctypes.
In this blog post, I would like to discuss the usage of ctypes for calling functions from C libraries.
Python C/C++ Library Binding
C Function Binding
When the C function only involves primitive C types, the function binding is extremely simple. In this case, we called memory copy functions from CUDA Runtime library libcudart and copied memory from host to device and from device to host.
# Allocate buffer on GPU. status = lib_cudart.cudaMalloc(ctypes.byref(d_ptr), ctypes.c_size_t(num_bytes)) assert status == 0
# Buffer copy from host to device and from device to host. # https://docs.nvidia.com/cuda/cuda-runtime-api/group__CUDART__TYPES.html#group__CUDART__TYPES_1g18fa99055ee694244a270e4d5101e95b status = lib_cudart.cudaMemcpy(d_ptr, h_ptr_input, ctypes.c_size_t(num_bytes), ctypes.c_int(1)) assert status == 0 status = lib_cudart.cudaMemcpy(h_ptr_output, d_ptr, ctypes.c_size_t(num_bytes), ctypes.c_int(2)) assert status == 0
# Free buffer on GPU. status = lib_cudart.cudaFree(d_ptr) assert status == 0
# Input and output buffers are equal now. assert np.array_equal(input_array, output_array)
C Structure Binding
In some scenarios, we will have to use non-primitive structures in C. Then we will have to create the corresponding structures in Python as well.
The following C code is the source code for a custom library libpoint which contains the C structure and function for Point.
ctypes were developed for supporting C libraries, its support for C++ functions and classes are very limited. If the function and class method only returns pointers instead of custom objects, it is possible to use ctypes for C++ function and class bindings. Please check the Stack Overflow thread for this. However, if the return type is custom objects, we cannot use ctypes for binding the C++ functions and classes. The interface will have to be re-designed.