I want to call a C++ function from Python that uses a complex array pointer as an argument.
My function looks like this.
extern "C" void myfunction(complex<float> *arr)
And I have made a library called mylib.so.
In Python, I have the following code to call the library (following: How to interface a NumPy complex array with C function using ctypes?):
complex_array = np.array([1+2j, 2+3j, 3+4j], dtype=np.complex64)
mylibrary_dll = CDLL('./mylib.so')
mylibrary_c = mylibrary_dll.myfunction
mylibrary_c.argtype = [np.ctypeslib.ndpointer(np.complex64,ndim=1,flags='c')]
And I am using:
mylibrary_c(complex_array.ctypes.data_as(POINTER(c_float)))
Reading Is it legal to cast float* to std::complex<float>*, I am not sure it is safe.
Should I use something like the following?
complex_array = np.array([1+2j, 2+3j, 3+4j], dtype=np.complex64)
# I define a new structure for complex
class Complex(ctypes.Structure):
_fields_ = [("real", ctypes.c_float),
("imag", ctypes.c_float)]
mylibrary_dll = CDLL('./mylib.so')
mylibrary_c = mylibrary_dll.myfunction
mylibrary_c.argtype = [POINTER(Complex)] # This is different from above
mylibrary_c(complex_array.ctypes.data_as(POINTER(Complex))) # This is different from above
as, in C++:
/// 26.2.3 complex specializations
/// complex<float> specialization
template<>
struct complex<float>
{
typedef float value_type;
typedef __complex__ float _ComplexT;
_GLIBCXX_CONSTEXPR complex(_ComplexT __z) : _M_value(__z) { }
_GLIBCXX_CONSTEXPR complex(float __r = 0.0f, float __i = 0.0f)
#if __cplusplus >= 201103L
: _M_value{ __r, __i } { }
#else
{
__real__ _M_value = __r;
__imag__ _M_value = __i;
}
#endif
extern "C"linkage that accepts arguments with C++ templated types. You should use POD types if this is a C API.