在 Python 中调用 C 函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16647186/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Calling C functions in Python
提问by Kitchi
I have a bunch of functions that I've written in C and I'd like some code I've written in Python to be able to access those functions.
我有一堆用 C 编写的函数,我希望我用 Python 编写的一些代码能够访问这些函数。
I've read several questions on here that deal with a similar problem (hereand herefor example) but I'm confused about which approach I need to take.
我在这里阅读了几个处理类似问题的问题(例如这里和这里),但我对我需要采取哪种方法感到困惑。
One question recommends ctypes and another recommends cython. I've read a bit of the documentation for both, and I'm completely unclear about which one will work better for me.
一个问题推荐 ctypes,另一个推荐 cython。我已经阅读了一些文档,我完全不清楚哪一个更适合我。
Basically I've written some python code to do some two dimensional FFTs and I'd like the C code to be able to see that result and then process it through the various C functions I've written. I don't know if it will be easier for me to call the Python from C or vice versa.
基本上,我已经编写了一些 python 代码来执行一些二维 FFT,我希望 C 代码能够看到该结果,然后通过我编写的各种 C 函数对其进行处理。我不知道从 C 调用 Python 对我来说是否更容易,反之亦然。
采纳答案by Gauthier Boaglio
If I understand well, you have no preference for dialoging as c => python or like python => c.
In that case I would recommend Cython. It is quite open to many kinds of manipulation, specially, in your case, calling a function that has been written in Python from C.
如果我理解得很好,你不喜欢像 c => python 或 python => c 这样的对话。在那种情况下,我会推荐Cython. 它对多种操作非常开放,特别是在您的情况下,从 C 调用用 Python 编写的函数。
Here is how it works (public api) :
这是它的工作原理(public api):
The following example assumes that you have a Python Class (selfis an instance of it), and that this class has a method (name method) you want to call on this class and deal with the result (here, a double) from C. This function, written in a Cython extensionwould help you to do this call.
下面的例子假设你有一个 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
On the C side, you'll then be able to perform the call like so :
在 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;
}
Where PyObjectis a structprovided by Python/C API
After having caught the py_obj(by casting a regular python object, in your cython extension like this : <PyObject *>my_python_object), you would finally be able to call the initSimulationmethod on it and do something with the result.
(Here a double, but Cython can deal easily with vectors, sets, ...)
Python/C API 提供的PyObjecta在哪里struct在捕获py_obj(通过object在像这样的 cython 扩展中投射常规 python : <PyObject *>my_python_object)之后,您最终将能够initSimulation在其上调用该方法并对结果执行某些操作。(这里 a double,但 Cython 可以轻松处理vectors, sets, ...)
Well, I am aware that what I just wrote can be confusing if you never wrote anything using Cython, but it aims to be a short demonstration of the numerous things it can do for you in term of merging.
好吧,我知道什么,我只是写可能会造成混淆,如果你从来没有使用任何东西写Cython,但它的目标是成为了无数东西它可以长期为你做一个简短的演示合并。
By another hand, this approach can take more time than recoding your Python code into C, depending on the complexity of your algorithms. In my opinion, investing time into learning Cython is pertinent only if you plan to have this kind of needs quite often...
另一方面,这种方法可能比将 Python 代码重新编码为 C 花费更多的时间,具体取决于算法的复杂性。在我看来,只有在您计划经常有这种需求的情况下,投入时间学习 Cython 才有意义......
Hope this was at least informative...
希望这至少是有用的...
回答by xuanji
It'll be easier to call C from python. Your scenario sounds weird - normally people write most of the code in python except for the processor-intensive portion, which is written in C. Is the two-dimensional FFT the computationally-intensive part of your code?
从 python 调用 C 会更容易。你的场景听起来很奇怪 - 通常人们用 python 编写大部分代码,除了用 C 编写的处理器密集部分。二维 FFT 是代码的计算密集部分吗?
回答by Florian Rhiem
You should call C from Python by writing a ctypeswrapper. Cython is for making python-like code run faster, ctypes is for making C functions callable from python. What you need to do is the following:
您应该通过编写ctypes包装器从 Python 调用 C。Cython 用于使类似 python 的代码运行得更快,ctypes 用于使 C 函数可从 python 调用。您需要做的是:
- Write the C functions you want to use. (You probably did this already)
- Create a shared object (.so, for linux, os x, etc) or dynamically loaded library (.dll, for windows) for those functions. (Maybe you already did this, too)
- Write the ctypes wrapper (It's easier than it sounds, I wrote a how-to for that)
- Call a function from that wrapper in Python. (This is just as simple as calling any other python function)
- 编写您要使用的 C 函数。(你可能已经这样做了)
- 为这些函数创建一个共享对象(.so,对于 linux、os x 等)或动态加载的库(.dll,对于 Windows)。(也许你也已经这样做了)
- 编写 ctypes 包装器(这比听起来容易,我为此写了一个操作方法)
- 在 Python 中从该包装器调用函数。(这就像调用任何其他python函数一样简单)
回答by Jadav Bheda
Well, here you are referring to two below things.
好吧,这里您指的是以下两件事。
- How to call c function within from python (Extending python)
- How to call python function/script from C program (Embedding Python)
- 如何在python中调用c函数(扩展python)
- 如何从 C 程序调用 python 函数/脚本(嵌入 Python)
For #2 that is 'Embedding Python'
对于 #2 是“嵌入 Python”
You may use below code segment:
您可以使用以下代码段:
#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; }
For #1 that is 'Extending Python'Then best bet would be to use Ctypes (btw portable across all variant of python).
对于 #1 是“扩展 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
从 ctypes 导入 *
libc = cdll.msvcrt
打印 libc.time(None)
1438069008
printf = libc.printf
printf("你好,%s\n", "世界!")
你好,世界!14
printf("%d 瓶啤酒\n", 42)
42瓶啤酒19
For detailed guide you may want to refer to my blog article:
有关详细指南,您可能需要参考我的博客文章:

