在Python中使用C函数
到目前为止,我已经尝试了互联网上提到的所有解决方案,但没有一个对我有效 我有一个python代码,为了加快速度,我希望我的代码在C函数中运行繁重的计算。 我已经写了这个C函数 然后,为了共享库,我在终端中执行了以下操作:在Python中使用C函数,python,c,python-3.x,ctypes,Python,C,Python 3.x,Ctypes,到目前为止,我已经尝试了互联网上提到的所有解决方案,但没有一个对我有效 我有一个python代码,为了加快速度,我希望我的代码在C函数中运行繁重的计算。 我已经写了这个C函数 然后,为了共享库,我在终端中执行了以下操作: gcc -shared -Wl,-install_name,testlib.so -o testlib.so -fPIC myModule.c 它不会返回错误。问题;当我尝试在python中启动C函数时出现。让我们考虑C:中的以下简单函数 int multiplier(int
gcc -shared -Wl,-install_name,testlib.so -o testlib.so -fPIC myModule.c
它不会返回错误。问题;当我尝试在python中启动C函数时出现。让我们考虑C:中的以下简单函数
int multiplier(int a, int b)
{
int lol = 0;
lol = a*b;
return lol;
}
我启动python3(3.5.2),然后:
import ctypes
zelib = ctypes.CDLL("/Users/longeard/Desktop/Codes/DraII/testlib.so",ctypes.RTLD_GLOBAL)
通过执行以下操作,该库应该可以在python中使用:
res = zelib.multiplier(2,3)
这样做时,它会工作,python会返回
6
问题是,我想要使用的函数(我使用的乘数函数只是示例)应该将浮点作为输入并返回浮点。但如果我现在考虑的乘数函数和以前一样,但用浮点:
float multiplier(float a, float b)
{
float lol = 0.0;
lol = a*b;
return lol;
}
我使用gcc重新编译,我重新导入ctypes并重新执行ctypes.CDLL,我在python3中执行:
zelib.multiplier(ctypes.c_float(2),ctypes.c_float(3))
(这里的types.c_float用于将python中的2转换为c中的float),python将返回:
2
这很奇怪,因为如果我在函数中添加printf来打印lol,python将打印:
6.0
但有时仍然返回2或18。即使我printf并返回相同的变量“lol”
我尝试了很多东西,但都没有成功。有人有主意吗?谢谢。您需要指定函数的
restype
,argtypes
:
zelib = ctypes.CDLL('...')
zelib.multiplier.restype = ctypes.c_float # return type
zelib.multiplier.argtypes = [ctypes.c_float, ctypes.c_float] # argument types
根据:
通过设置argtypes
属性,可以指定从DLL导出的函数所需的参数类型
以及:
默认情况下,假定函数返回C int类型。通过设置函数对象的restype
属性,可以指定其他返回类型
虽然@falsetru的答案是更好的方法,但另一种方法是简单地编写C函数来使用double
当调用一个没有参数列表的函数时,浮点数会自动升级为双精度。谢谢,效果非常好!事实上,我昨天已经试过好几次了,因为某些原因,它不起作用,但现在起作用了。很抱歉,我重复了这句话。。。。在这种情况下,您知道如何将numpy float数组作为输入传递吗?并在C函数中返回一个数组?谢谢。@Nicano,看看这个:如果你有更多的问题,请把它作为另一个问题发布。
# without specifying types
>>> import ctypes
>>> zelib = ctypes.CDLL('testlib.so')
>>> zelib.multiplier(2, 3)
0
# specifying types
>>> zelib.multiplier.restype = ctypes.c_float
>>> zelib.multiplier.argtypes = [ctypes.c_float, ctypes.c_float]
>>> zelib.multiplier(2, 3)
6.0