PyObject
)表示到Python(object
)表示。 - Gauthier Boaglioarray_type = ctypes.c_int * num_numbers
result = _sum.our_function(ctypes.c_int(num_numbers), array_type(*numbers))
这个过程会创建 numbers
列表的副本吗? - mercury0114如果我理解正确,你对于像 c => python 或者 python => c 的对话没有偏好。
在这种情况下,我建议使用 Cython
。它非常适合各种操作,特别是在你的情况下,从 C 调用已经在 Python 中编写的函数。
以下是它的工作方式(public api
):
以下示例假定你有一个 Python 类(self
是它的实例),并且该类有一个方法(名为 method
),你想在 C 中调用该方法并处理结果(这里是一个 double
)。这个函数是在一个 Cython 扩展
中编写的,可以帮助你进行这个调用。
cdef public api double cy_call_func_double(object self, char* method, bint *error):
if (hasattr(self, method)):
error[0] = 0
return getattr(self, method)();
else:
error[0] = 1
PyObject *py_obj = ....
...
if (py_obj) {
int error;
double result;
result = cy_call_func_double(py_obj, (char*)"initSimulation", &error);
cout << "Do something with the result : " << result << endl;
}
在Python / C API中提供了一个名为PyObject
的结构体。在您的Cython扩展中,通过将常规python object
强制转换为<PyObject *>my_python_object
,您可以捕获py_obj
,最终可以在其上调用initSimulation
方法并对结果进行操作(这里是一个double
,但Cython可以轻松处理vectors
,sets
,...)。
如果您从未使用过Cython
编写任何内容,则我知道我刚刚写的可能会令人困惑,但它旨在简短地演示它在合并方面可以为您做的许多事情。
cout
是<iostream>
的一部分,对吗? - Ayxan Haqverdili这里涉及到以下两个问题:
对于第二个问题即“嵌入Python”,您可以使用以下代码片段:
#include "python.h"
int main(int argc, char *argv[]) {
Py_SetProgramName(argv[0]); /* optional but recommended */
Py_Initialize();
PyRun_SimpleString("from time import time,ctime\n"
"print 'Today is',ctime(time())\n");
/*Or if you want to run python file within from the C code*/
//pyRun_SimpleFile("Filename");
Py_Finalize();
return 0; }
对于第一个问题,即'扩展 Python'
最好的方法是使用 Ctypes(顺便说一下,它在所有变体的 Python 中都可移植)。
>> from ctypes import *
>> libc = cdll.msvcrt
>> print libc.time(None)
>> 1438069008
>> printf = libc.printf
>> printf("Hello, %s\n", "World!")
>> Hello, World!
14
>> printf("%d bottles of beer\n", 42)
>> 42 bottles of beer
19
如果您想要详细的指南,可以参考我的博客文章:
从Python调用C会更容易。您的情况听起来有些奇怪 - 通常人们大部分代码都是用Python编写的,除了处理计算密集型部分,这部分会使用C语言编写。两维FFT是否是您代码中计算密集型的部分?
这里有一篇简洁明了的教程,来自Digital Ocean。简要版:
1. 编写 C 代码
你已经完成了这个步骤,以下是一个超级简短的示例:
#include <stdio.h>
int addFive(int i) {
return i + 5;
}
2. 创建共享库文件
假设上述C文件已保存为c_functions.c
,则在终端中输入以下命令以生成.so
文件以从Python调用:
cc -fPIC -shared -o c_functions.so c_functions.c
3. 在Python中使用您的C代码!
在您的Python模块中:
# Access your C code
from ctypes import *
so_file = "./c_functions.so"
c_functions = CDLL(so_file)
# Use your C code
c_functions.addFive(10)
最后一行将输出15。你完成了!
BLimitless引用Digital Ocean的答案对于简单情况是可以的,但它默认只允许int类型的参数。如果需要不同类型的输入参数,例如float类型,您需要添加以下内容:
c_functions.addFive.argtypes=[ctypes.c_float]
如果你改变输出参数,例如改为浮点数类型,你需要这样做:
c_functions.addFive.restype=ctypes.c_float