标签: python-embedding

从C/C++调用python方法,并提取其返回值

我想调用一个在C语言的python模块中定义的自定义函数.我有一些初步代码可以做到这一点,但它只是将输出打印到stdout.

mytest.py

import math

def myabs(x):
    return math.fabs(x)
Run Code Online (Sandbox Code Playgroud)

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

如何将返回值提取到C double并在C中使用它?

c c++ python python-embedding python-c-api

49
推荐指数
4
解决办法
6万
查看次数

使用Python的C API创建对象

假设我的对象布局定义为:

typedef struct {
    PyObject_HEAD
    // Other stuff...
} pyfoo;
Run Code Online (Sandbox Code Playgroud)

...和我的类型定义:

static PyTypeObject pyfoo_T = {
    PyObject_HEAD_INIT(NULL)
    // ...

    pyfoo_new,
};
Run Code Online (Sandbox Code Playgroud)

如何pyfoo在C扩展中的某个位置创建新实例?

c python python-embedding python-c-api python-extensions

41
推荐指数
1
解决办法
1万
查看次数

如何在c ++代码中捕获python stdout

我有一个程序,在它运行期间有时需要调用python来执行某些任务.我需要一个调用python并捕获pythons stdout并将其放入某个文件的函数.这是函数的声明

  pythonCallBackFunc(const char* pythonInput)
Run Code Online (Sandbox Code Playgroud)

我的问题是捕获给定命令(pythonInput)的所有python输出.我没有python API的经验,我不知道什么是正确的技术来做到这一点.我尝试过的第一件事是使用Py_run_SimpleString重定向python的sdtout和stderr,这是我编写的代码的一些例子.

#include "boost\python.hpp"
#include <iostream>

void pythonCallBackFunc(const char* inputStr){   

    PyRun_SimpleString(inputStr); 
}


int main () {
    ...
   //S0me outside functions does this
   Py_Initialize();
   PyRun_SimpleString("import sys");
   PyRun_SimpleString("old_stdout = sys.stdout");
   PyRun_SimpleString("fsock = open('python_out.log','a')");
   PyRun_SimpleString("sys.stdout = fsock");
   ...

   //my func   
   pythonCallBackFunc("print 'HAHAHAHAHA'");
   pythonCallBackFunc("result = 5");
   pythonCallBackFunc("print result");

   pythonCallBackFunc("result = 'Hello '+'World!'");
   pythonCallBackFunc("print result");

   pythonCallBackFunc("'KUKU '+'KAKA'");
   pythonCallBackFunc("5**3");

   pythonCallBackFunc("prinhghult");

   pythonCallBackFunc("execfile('stdout_close.py')");
   ... 

   //Again anothers function code
   PyRun_SimpleString("sys.stdout = old_stdout");
   PyRun_SimpleString("fsock.close()");

   Py_Finalize();
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

有一个更好的方法吗?此外,由于某种原因PyRun_SimpleString在得到一些数学表达式时什么都不做,例如PyRun_SimpleString("5**3")什么都不打印(python …

c++ python redirect python-embedding python-c-api

25
推荐指数
3
解决办法
1万
查看次数

从C/C++程序调用多个操作系统线程上的多个独立嵌入式Python解释器

C/C++应用程序中嵌入Python解释器已有详细记录.在C/C++应用程序中调用的多个操作系统线程(即同一进程中的一个操作系统线程上的一个解释器)上运行多个python解释器的最佳方法是什么?此类应用程序也可能存在与内存碎片和Py_Finalize()限制相关的问题.

一种这样的方法可以是:

  1. Python线程,因此在pyconfig.h中禁用GIL以保持简单(#undef WITH_THREAD)
  2. Python解释器源代码的所有可变全局变量都移动到通过线程本地存储引用的堆分配结构(参考:电话上的Python).

我的问题是:

  1. 有没有更好的方法?
  2. 是否有任何工具可以自动将Python解释器源代码的全局变量转换为通过TLS(线程本地存储)引用的堆分配结构?

这里讨论类似的主题:

python thread-local python-embedding

22
推荐指数
1
解决办法
6366
查看次数

是否可以将PyPy嵌入到.NET应用程序中?

我想在我的.NET应用程序中嵌入一个Python解释器.我当然知道IronPython,但我对PyPy特别感兴趣,因为它支持无堆栈和微线程.

但是,虽然可以针对CLI构建PyPy,但它看起来只是为您提供了一个独立的Python解释器和python.exe.我无法找到任何可以构建实际嵌入.NET宿主应用程序内容的文档.

有没有办法使用(无堆栈)PyPy从.NET应用程序运行Python脚本,并允许这些脚本与主机应用程序提供的CLR对象进行交互?

.net python pypy python-embedding python-stackless

17
推荐指数
1
解决办法
1465
查看次数

在多线程C应用程序中嵌入python

我在一个多线程的C应用程序中嵌入python解释器,我有点困惑的是我应该使用什么API来确保线程安全.

从我收集的内容来看,嵌入python时,在调用任何其他Python C API调用之前,由嵌入器来处理GIL锁.这是通过以下功能完成的:

gstate = PyGILState_Ensure();
// do some python api calls, run python scripts
PyGILState_Release(gstate);
Run Code Online (Sandbox Code Playgroud)

但仅凭这一点似乎还不够.我仍然有随机崩溃,因为它似乎不提供Python API的互斥.

在阅读了更多文档后,我还补充说:

PyEval_InitThreads();
Run Code Online (Sandbox Code Playgroud)

在电话会议结束后,Py_IsInitialized()这就是令人困惑的部分.文档声明这个函数:

初始化并获取全局解释器锁

这表明当这个函数返回时,GIL应该被锁定并且应该以某种方式解锁.但实际上这似乎并不是必需的.有了这条线,我的多线程工作完美,并且PyGILState_Ensure/Release功能保持互斥.
当我尝试PyEval_ReleaseLock()PyEval_ReleaseLock()应用程序死锁后很快在后续调用中添加PyImport_ExecCodeModule().

那我在这里错过了什么?

c python multithreading python-embedding gil

17
推荐指数
2
解决办法
5230
查看次数

如何让cmake找到pybind11

我正在尝试遵循本页上找到的使用 pybind11 在 c++ 中嵌入 python 的简单示例。但是,当尝试使用 cmake 构建解决方案时,我不断收到一条错误消息:

通过不在 CMAKE_MODULE_PATH 中提供“Findpybind11.cmake”,该项目要求 CMake 查找“pybind11”提供的包配置文件,但 CMake 没有找到。

找不到“pybind11”提供的具有以下任何名称的包配置文件:

pybind11Config.cmake
pybind11-config.cmake
Run Code Online (Sandbox Code Playgroud)

我的桌面上有一个名为 pybindtest 的文件夹,其中包括上面链接中所述的 CMakeLists.txt 和 main.cpp,以及我创建的构建文件夹。在构建文件夹中,我尝试了以下几行但无济于事(在 Powershell 7 上运行):

cmake ..
cmake .. -Dpybind11_DIR=C:/Users/ben.wolfley/Anaconda3/Library/share/cmake/pybind11/pybind11Config.cmake
cmake .. -DCMAKE_MODULE_PATH=C:/Users/ben.wolfley/Anaconda3/Library/share/cmake/pybind11
Run Code Online (Sandbox Code Playgroud)

我使用安装了 pybind11 conda install pybind11,并且 pybind11Config.cmake 位于C:\Users\ben.wolfley\Anaconda3\Library\share\cmake\pybind11

c++ powershell cmake python-embedding pybind11

15
推荐指数
2
解决办法
2万
查看次数

我的嵌入式python stdout在哪里?

考虑以下MWE:

#include <Python.h>
#include <stdio.h>

int main(void) {
  printf("Test 1\n");
  Py_Initialize();
  printf("Test 2\n");
  PyRun_SimpleString("print('Test 3')");
  printf("Test 4\n");
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我正常编译并运行时,我得到预期的输出:

$ ./test
Test 1
Test 2
Test 3
Test 4
Run Code Online (Sandbox Code Playgroud)

但是当我重定向输出时,我从python代码中得不到任何东西:

$ ./test | cat
Test 1
Test 2
Test 4
Run Code Online (Sandbox Code Playgroud)

怎么了?更重要的是,如何将我的python输出写入stdout,如预期的那样?

python python-embedding python-3.4

14
推荐指数
2
解决办法
542
查看次数

使用动态版本的Python执行嵌入式python代码时出现致命的Python错误

SPOILER:部分解决(见最后).

以下是使用Python嵌入的代码示例:

#include <Python.h>
int main(int argc, char** argv)
{
    Py_SetPythonHome(argv[1]);
    Py_Initialize();
    PyRun_SimpleString("print \"Hello !\"");
    Py_Finalize();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我使用gcc 4.8.5在Linux openSUSE 42.2下工作(但我在使用gcc 4.8.3的openSUSE 13.2或使用gcc 4.4.7的RedHat 6.4时也遇到了同样的问题).

我编译了Python 2.7.9的静态和动态版本(但我在Python 2.7.13中也遇到了同样的问题).

我使用以下命令编译链接到Python静态版本的示例:

g++ hello.cpp -o hello \
-I /home/caduchon/softs/python/2.7.9/64/gcc/4.8.5/static/include/python2.7 \
-L /home/caduchon/softs/python/2.7.9/64/gcc/4.8.5/static/lib \
-l python2.7 -l pthread -l util -l dl
Run Code Online (Sandbox Code Playgroud)

如果我在参数中使用静态版本的Python执行我的示例,它就可以工作.

如果我在参数的动态版本的Python上执行它,我会收到以下错误(它发生在Py_Initialize()):

> ./hello /home/caduchon/softs/python/2.7.9/64/gcc/4.8.5/dynamic
Fatal Python error: PyThreadState_Get: no current thread
Aborted (core dumped)
Run Code Online (Sandbox Code Playgroud)

我不知道为什么它适用于静态版本,它不适用于动态版本.我该如何解决这类问题?

编辑:我安装Python的脚本如下:

#!/bin/bash

WORKDIR=/home/caduchon/tmp/install_python_2_7_13
ARCHIVEDIR=/home/caduchon/downloads/python
PYTHON_VERSION='2.7.13'
EZ_SETUP_VERSION='0.9'
SETUPTOOLS_VERSION='34.1.0'
CYTHON_VERSION='0.25.2'
NUMPY_VERSION='1.12.0'
SCIPY_VERSION='0.18.1' …
Run Code Online (Sandbox Code Playgroud)

c++ python python-embedding boost-python

14
推荐指数
1
解决办法
653
查看次数

当从C++应用程序中的嵌入式Python调用时,Numpy导入在多数组扩展库上失败

我正在运行一个C++应用程序,它尝试使用https://docs.python.org/3.5/extending/embedding.html函数调用来运行python .这是应用程序错误消息管道给我的错误.

class'ImportError':导入多阵列numpy扩展模块失败.您很可能正在尝试导入失败的numpy版本.如果您正在使用numpy git repo,请尝试git clean -xdf(删除不受版本控制的所有文件).否则重新安装numpy.

原始错误是:/usr/local/lib/python3.5/site-packages/numpy/core/multiarray.cpython-35m-x86_64-linux-gnu.so:undefined symbol:PyExc_UserWarning

我很困惑,因为只有当我在C++中嵌入Python时才会出现这种情况,因为当我通过解释器使用它时导入工作.我对答案更感兴趣,这个答案增加了我的理解,而不是快速做到这一点或做了那个修复.我列出了下面的一些系统/问题信息,以及我正在考虑发布关于同一主题的一些其他问题.任何指导表示赞赏!

系统/问题信息:

  • Ubuntu 16.04,64位
  • 使用enabled-shared编译的Python 3.5.5
  • numpy导入在解释器中工作(python3.exe和python3.5.exe)
  • 我已经确定了PySys_SetPath()设置相同的sys.path从翻译的输出:import sys,sys.path
  • 我可以导入其他模块,如PIL和datetimeutil; 然而,numpy和pandas是不可导入的(熊猫使用numpy或似乎)
  • 嵌入式Python使用下面的命令:Py_Import_Import(),Py_Initialize()(我确信它只能调用一次.)等,但它并没有得到解释的全局锁.
  • 该应用程序使用CMake构建系统构建,该系统为我的系统编译MakeFiles.
  • 使用pip3.5 install numpy命令使用pip 9.0.0安装numpy-1.14.2
  • 导致此错误的python脚本有一行:import numpy...
  • 我没有我要导入文件的.zip文件.
  • 嵌入在C++中的Python使用的.exe位于/ usr/local/bin/python3(使用Py_GetProgramName()来确定这一点).此.exe链接到libpython3.5m.so.1.0,缺少的符号位于libpython3.5m.so.1.0(运行nm)
  • ldd on multiarray.cpython-35m-x86_64-linux-gnu.so显示:

    ldd multiarray.cpython-35m-x86_64-linux-gnu.so

    linux-vdso.so.1 =>(0x00007ffd9e36b000)

    libopenblasp-r0-39a31c03.2.18.so => /usr/local/lib/python3.5/site-packages/numpy/core/./../.libs/libopenblasp-r0-39a31c03.2.18.so(0x00007fdbe149b000)

    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6(0x00007fdbe1192000)

    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0(0x00007fdbe0f75000)libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6(0x00007fdbe0bab000)/ lib64 /ld-linux-x86-64.so.2(0x00007fdbe3ed5000)

    libgfortran-ed201abd.so.3.0.0 => /usr/local/lib/python3.5/site-packages/numpy/core/./../.libs/libgfortran-ed201abd.so.3.0.0(0x00007fdbe08b1000)

我可以/可能会尝试通过不同的方式重新安装numpy,但我无法跟踪为什么这可能会起作用.

在这一点上,我假设我的知识存在一些漏洞.我已经看过很多关于在C++中嵌入Python时无法导入多阵列组件和numpy的类似帖子; 但是,要么它们都不符合我的具体情况,要么就像我说的那样存在漏洞.以下是我可能会问的一个子问题列表,如果没有人在这个设置中看到任何明显有关的内容.如果我问他们(在我擦亮之后),我可能会用链接更新问题.

  • numpy multiarray.so如何链接到pythonX.X.so以进行符号解析?ldd似乎没有暗示它曾经做过.在这个链接上问这个问题
  • 在这个解决问题的CMake不相关的问题的问题问及18年4月12日,并回答了在18年4月16日.
  • 在.bashrc中设置PYTHONPATH似乎不会更新Py_GetPath()返回的内容,我不得不通过与sys.path不同的方法在site-packages中添加导入.它可能只更新不影响C++的bash脚本环境变量. …

c++ python numpy python-embedding python-3.x

11
推荐指数
1
解决办法
817
查看次数