如何在Python中使用具有复杂类型的C函数?

如何在Python中使用具有复杂类型的C函数?,python,c,complex-numbers,Python,C,Complex Numbers,我决定将我的一些Python函数移植到C中,主要如下所示。问题是我的C函数返回一个复杂的浮点,而ctypes函数中并没有相应的类型。这是一个我自己无法解决的问题,因为我在跨语言编码和C语言方面的知识有限,甚至被Google扩展 我的C函数的工作原理如下: #include <tgmath.h> float _Complex integrand(float _Complex theta1, double r, double z){ //[code] } complextype

我决定将我的一些Python函数移植到C中,主要如下所示。问题是我的C函数返回一个复杂的浮点,而ctypes函数中并没有相应的类型。这是一个我自己无法解决的问题,因为我在跨语言编码和C语言方面的知识有限,甚至被Google扩展

我的C函数的工作原理如下:

#include <tgmath.h>
float _Complex integrand(float _Complex theta1, double r, double z){
    //[code] }
complextype = '??????'

_integr = ctypes.CDLL('libintegrand.so')
_integr.integrand.argtypes = (complextype, ctypes.c_double, ctypes.c_double)

def integrand(theta1, r, z):
    global _integr
    result = _integr.integrand(complextype(theta1), ctypes.c_double(r), ctypes.c_double(z))
    return float(result)
但是这种类型应该是什么呢?我该怎么做


如果函数也有一个复杂的参数这一事实使它变得更加复杂,请忽略这个复杂的参数。

天真地说,也许可以将它分成两个参数,
Re(z),Im(z)
如果这不是一个选项,可以将参数传递给python函数
complex()

这些都是幼稚的解决方案;也许它们不起作用,但如果你没有考虑到这一点,并且没有更好的反应,可能值得尝试一下


祝你好运

创建一个小型C包装函数:

void integrand_wrapper(float *re, float *im, double r, double z)
{
    float _Complex  result;
    float _Complex  theta = (*re) + I*(*im);
    result = integrand(theta, r, z);
    (*re) = creal(result);
    (*im) = cimag(result);
}
调用时,
re
im
指针保存
theta
的实部和虚部,然后保存结果的实部和虚部

在Python代码中,使用例如

def integrand(theta, r, z):
    global _integr
    theta = complex(theta)
    re = c_float(theta.real)
    im = c_float(theta.imag)
    _integr.integrand_wrapper(byref(re), byref(im), c_double(r), c_double(z))
    return complex(float(re), float(im))
请注意,如果在无法修改的二进制库中定义了
integrand()
,则始终可以创建另一个仅包含
integrand\u wrapper
的动态库,该库动态链接(在C中)到原始二进制库


总的来说,我认为增加的开销一点也不重要。这当然值得测试。

我也遇到过拆分值的情况,但不幸的是,这会严重损害目标(性能改进),因为我必须对所有内容进行两次计算。还有一些昂贵的功能。也许我可以把它们放在一个数组里,不过最后。。。嗯。顺便说一句,您的
global\u integr
语句是不必要的,并且oykd可能会导致有经验的Python程序员假设此函数在不改变全局状态时会改变全局状态