从 C/C++ 调用 python 方法,并提取其返回值
我想从 C 调用在 Python 模块中定义的自定义函数。我有一些初步代码可以做到这一点,但它只是将输出打印到 stdout。
mytest.py
import math
def myabs(x):
return math.fabs(x)
test.cpp
#include <Python.h>
int main() {
Py_Initialize();
PyRun_SimpleString("import sys; sys.path.append('.')");
PyRun_SimpleString("import mytest;");
PyRun_SimpleString("print mytest.myabs(2.0)");
Py_Finalize();
return 0;
}
如何将返回值提取到 C double
中并在 C 中使用它?
I'd like to call a custom function that is defined in a Python module from C. I have some preliminary code to do that, but it just prints the output to stdout.
mytest.py
import math
def myabs(x):
return math.fabs(x)
test.cpp
#include <Python.h>
int main() {
Py_Initialize();
PyRun_SimpleString("import sys; sys.path.append('.')");
PyRun_SimpleString("import mytest;");
PyRun_SimpleString("print mytest.myabs(2.0)");
Py_Finalize();
return 0;
}
How can I extract the return value into a C double
and use it in C?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
如前所述,使用 PyRun_SimpleString 似乎是一个坏主意。
您绝对应该使用 C-API 提供的方法 (http://docs.python.org/c -api/)。
阅读简介是了解其工作方式的第一件事。
首先,您必须了解 PyObject,它是 C API 的基本对象。它可以表示任何类型的Python基本类型(字符串、浮点数、整数……)。
存在许多函数可以将 python 字符串转换为 char* 或 PyFloat 转换为 double。
首先,导入你的模块:
然后获取对你的函数的引用:
然后获取你的结果:
并返回到双精度:
你显然应该检查错误(参见 Mark Tolonen 给出的链接)。
如果您有任何疑问,请不要犹豫。祝你好运。
As explained before, using PyRun_SimpleString seems to be a bad idea.
You should definitely use the methods provided by the C-API (http://docs.python.org/c-api/).
Reading the introduction is the first thing to do to understand the way it works.
First, you have to learn about PyObject that is the basic object for the C API. It can represent any kind of python basic types (string, float, int,...).
Many functions exist to convert for example python string to char* or PyFloat to double.
First, import your module :
Then getting a reference to your function :
Then getting your result :
And getting back to a double :
You should obviously check the errors (cf. link given by Mark Tolonen).
If you have any question, don't hesitate. Good luck.
下面是我编写的示例代码(在各种在线资源的帮助下),用于将字符串发送到 Python 代码,然后返回一个值。
这是 C 代码
call_function.c
:这是 Python 代码,位于文件
arbName.py
中:我使用命令
gcc call_function.c -I/usr /include/python2.6 -lpython2.6 ; ./a.out
来运行此进程。我是红帽的我建议使用 PyErr_Print();用于错误检查。Here is a sample code I wrote (with the help of various online sources) to send a string to a Python code, then return a value.
Here is the C code
call_function.c
:Here is the Python code, in file
arbName.py
:I use the command
gcc call_function.c -I/usr/include/python2.6 -lpython2.6 ; ./a.out
to run this process. I'm on redhat. I recommend using PyErr_Print(); for error checking.调用 Python 函数并检索结果的完整示例位于 http://docs.python.org/release/2.6.5/extending/embedding.html#pure-embedding:
A complete example of calling a Python function and retrieving the result is located at http://docs.python.org/release/2.6.5/extending/embedding.html#pure-embedding:
为了防止像其他答案中那样出现额外的 .py 文件,您只需检索 __main__ 模块,该模块是由第一次调用
PyRun_SimpleString
创建的:To prevent the extra .py file as in the other answers, you can just retrieve the
__main__
module, which is created by the first call toPyRun_SimpleString
:正如其他人已经提到的,这个问题在 Python 文档 中得到了回答。然而,由于我来自 Python,并且没有太多使用 C/C++ 的经验,所以我在使用 Python 3 运行它时遇到了一些问题。因此,这是我在其他帖子上花费一些时间后运行 Python 文档的完整工作示例stackoverflow 的:
文件
c_function.c
文件
multiply.py
我们需要编译并链接它。这可以通过以下命令来完成:
后跟
对于 Python 3.6 的示例, 命令。之后,Python 文档中的示例可以通过以下方式执行
As others have already mentioned, this is answered at the Python docs. However, since I come from Python and don't have that much experience using C/C++, I had some issues running it with Python 3. So here is my full working example to get the Python docs running after spending some time on other posts of stackoverflow:
File
c_function.c
File
multiply.py
We need to compile and link it. This can be done with the command:
followed by
for the example of Python 3.6. Afterwards, the example from the Python docs can just be executed by
这是一个最小的可执行版本,也适用于 Python 3(使用 Python 2.7 和 3.9 进行测试)。
注释中包含文档的链接,但所有链接都可以在 https://docs 下访问。 python.org/3/c-api/
这使用 OP 的 Python 代码
mytest.py
,或这一行等效项:构建将是特定于 OS/Python 版本的,但是以下对我有用:
Here's a minimal executable version that also works with Python 3 (tested with Python 2.7 and 3.9).
Links into the docs are included in the comments, but all are accessible under https://docs.python.org/3/c-api/
This uses the OP's Python code
mytest.py
, or this one-line equivalent:Building is going to be OS/Python version specific, but the following works for me:
您必须以某种方式提取 python 方法并使用
PyObject_CallObject()
运行它。为此,您可以为 Python 提供一种设置函数的方法,如 扩展和嵌入 Python 教程 示例就是如此。You have to extract the python method somehow and run it with
PyObject_CallObject()
. To do that, you can provide Python a way to set the function, as the Extending and Embedding Python Tutorial example does.如果将返回值分配给变量,则可以使用 PyEval_GetGlobals() 和 PyDict_GetItemString() 之类的方法来获取 PyObject。从那里,PyNumber_Float 可以得到你想要的值。
我建议浏览整个 API - 当您看到可用的不同方法时,某些事情就会变得显而易见,并且很可能有比我所描述的方法更好的方法。
If you assign the return value to a variable, then you can use something like PyEval_GetGlobals() and PyDict_GetItemString() to get the PyObject. From there, PyNumber_Float can get you the value you want.
I suggest browsing through the whole API - certain things become obvious when you see the different methods that are available to you, and there may well be a better method than the one I've described.
我已经使用 BOOST 将 Python 嵌入到 C++ 中完成了[这个工作 C 模块应该有帮助]
I have done it using BOOST to embedded Python to C++ [This working C module should help]
这是对您的问题的简单而直接的回答:
Here is a simple and direct answer to your question: