Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中使用C函数_Python_C_Python 3.x_Ctypes - Fatal编程技术网

在Python中使用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

到目前为止,我已经尝试了互联网上提到的所有解决方案,但没有一个对我有效

我有一个python代码,为了加快速度,我希望我的代码在C函数中运行繁重的计算。 我已经写了这个C函数

然后,为了共享库,我在终端中执行了以下操作:

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