在 Python 中使用 C 函数

Using a C function in Python

到目前为止,我已经尝试了互联网上提到的所有解决方案。

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

然后,为了共享库,我在终端中这样做了:

gcc -shared -Wl,-install_name,testlib.so -o testlib.so -fPIC myModule.c

其中 return 没有错误。问题;当我尝试在 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 returns

6

问题是,我想使用的函数(我使用的乘数函数仅用于示例)应该将浮点数作为输入,return 一个浮点数。但是,如果我现在考虑与以前相同的乘数函数但使用 float :

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 中的浮点数),python 将 return :

2

这很奇怪,因为如果我在函数中添加一个 printf 来打印 lol,python 将打印:

  6.0

但仍然 return 2,有时是 18。即使我 printf 和 return 相同的变量 "lol".

我尝试了很多东西,none 成功了。请问有人有想法吗?谢谢。

您需要指定函数的restypeargtypes:

zelib = ctypes.CDLL('...')
zelib.multiplier.restype = ctypes.c_float   # return type
zelib.multiplier.argtypes = [ctypes.c_float, ctypes.c_float]  # argument types

根据Specifying the required argument types (function prototypes)

It is possible to specify the required argument types of functions exported from DLLs by setting the argtypes attribute.

Return types in ctypes module documentation

By default functions are assumed to return the C int type. Other return types can be specified by setting the restype attribute of the function object.


# 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

虽然@falsetru 的回答是更好的方法,但另一种方法是简单地编写 C 函数以使用双精度数。

在调用没有参数列表的函数时,浮点数自动提升为双精度值。