在Python中调用C函数

Kit*_*chi 30 c python ctypes cython

我有一堆用C编写的函数,我想要一些用Python编写的代码来访问这些函数.

我在这里已经阅读了几个处理类似问题的问题(例如这里这里),但我对我需要采取哪种方法感到困惑.

一个问题推荐ctypes,另一个推荐cython.我已经阅读了两篇文档,我完全不清楚哪一个对我有用.

基本上我已经写了一些python代码来做一些二维FFT,我希望C代码能够看到那个结果然后通过我编写的各种C函数来处理它.我不知道我是否更容易从C调用Python,反之亦然.

Flo*_*iem 56

你应该通过编写一个ctypes包装器从Python调用C语言.Cython用于使类似python的代码运行得更快,ctypes用于使C函数可以从python调用.您需要做的是以下内容:

  1. 编写要使用的C函数.(你可能已经这样做了)
  2. 为这些函数创建一个共享对象(.so,对于linux,os x等)或动态加载的库(.dll,对于Windows).(也许你已经这样做了)
  3. 编写ctypes包装器(它比听起来容易,我写了一个方法)
  4. 从Python中的包装器调用一个函数.(这就像调用任何其他python函数一样简单)


Gau*_*lio 10

如果我理解得很好,你就不喜欢像c => python或python => c那样进行对话.在那种情况下,我会建议Cython.对于多种操作非常开放,特别是在你的情况下,调用一个用C语言编写的函数.

这是它的工作原理(public api):

下面的示例假定您有一个Python类(self是它的一个实例),并且该类有一个method您想要在此类上调用的方法(名称)并double从C 处理结果(此处为a ).此函数写在一个Cython extension会帮助你做这个电话.

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
Run Code Online (Sandbox Code Playgroud)

在C方面,您可以像这样执行调用:

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;
}
Run Code Online (Sandbox Code Playgroud)

PyObjectstruct被Python/C API已经抓到后提供py_obj(通过铸造常规的Python object,在你用Cython扩展这样的:<PyObject *>my_python_object),你将最终能够调用的initSimulation方法就可以了,做什么用的结果.(这里的一个double,但用Cython可以轻松应对vectors,sets...)

好吧,我知道如果你从来没有写过任何东西Cython,我刚刚写的东西可能会令人困惑,但它的目的是简短地展示它在合并方面可以为你做的众多事情.

另一方面,这种方法比将代码重新编码为C需要更多的时间,具体取决于算法的复杂程度.在我看来,只有当你计划经常有这种需求时,花时间学习Cython才是恰当的...

希望这至少可以提供信息......


Jad*_*eda 5

嗯,这里你指的是以下两件事。

  1. 如何从 python 中调用 c 函数(扩展 python)
  2. 如何从 C 程序调用 python 函数/脚本(嵌入 Python)

对于#2,即“嵌入 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; }
Run Code Online (Sandbox Code Playgroud)

对于#1 “扩展Python”, 那么最好的选择是使用Ctypes(顺便说一句,可以跨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; }
Run Code Online (Sandbox Code Playgroud)

有关详细指南,您可能需要参考我的博客文章