【问题标题】:Embedding Python in C/C++在 C/C++ 中嵌入 Python
【发布时间】:2020-01-16 04:08:54
【问题描述】:

对于我的计算机科学高级项目,我正在制作一款益智视频游戏,教人们如何使用 Python 进行编码。设计的最大部分涉及创建用户可以排序的引人入胜的谜题。不过,拼图设计不是我目前遇到的问题。

虽然我最初的想法是让每个“问题”都有一系列预期的答案来检查用户的答案,但我学校的 CS 部门负责人(负责举办高级研讨会)建议我改用嵌入式 Python,他建议既挑战我,又让数据更容易嵌入一个简单的解释器,它将检查用户代码输出与预期输出。

四个星期后,我学到了很多关于 Python 实际工作原理的知识。我什至让解释器将 simple C 字符串 作为 python 代码,比如 print("hello") 或 print("hello/tworld"),只要 C 字符串中没有空格.

那个代码看起来像

#include "pch.h"
#include <iostream>
#include <string>
#include <fstream>
#include <Python.h>

void exec_pycode(const char* code);

int main()
{
    using namespace std;
    Py_Initialize();

    string input;

    cin >> input;
     /*Though the variable gets passed to a const char* definition,
    the pointer is constant over the character, because the pointer ALWAYS points
    to the same function*/
    char const *PyCode = input.data();

    exec_pycode(PyCode);        

    Py_Finalize();
    return EXIT_SUCCESS;    
}        

//The execution of python code as a simple string in C and interpreting in python
void exec_pycode(const char* code)
{
    Py_Initialize();
    PyRun_SimpleString(code);
    Py_Finalize();
}

我决定的下一步是包含诸如 print("hello world") 空格之类的字符串,以 Python 代码的形式可读。

我已尝试将 exec 代码函数更改为如下所示

void exec_pycode(const char* code)
{
    Py_Initialize();
    const char *inFile = "FileName";
    PyObject *dict = PyDict_New();
    Py_CompileString(code, inFile, Py_file_input);
    PyRun_String(code, Py_file_input, dict, dict);

    Py_Finalize();
}

当函数像这样改变时,这编译得很好,但是当我输入任何字符串,简单或带有空格时,程序以返回值 0 退出,而不打印任何 python 代码。

我很好奇为什么会发生这种情况,是否在将用户输入转换为足够的 C 字符串以读取为 Python 代码时遇到问题,或者它不理解 Py_CompileString(const char *str, const char *filename, int start)PyRun_String(const char *str, int start, PyObject *globals, PyObject *locals)、@ 的声明987654321@.

我也想知道:

  1. 如果我要声明 Python 字符串命令的字典以正确读取代码,或者是
  2. 如果在简化版本中将我的 Python 文件标志设置为 NULL 而不是 Py_CompileStrngFlags(...)Py_RunStringFlags(...),这就是导致我遇到的 NULL 问题的返回值的原因。
  3. 如果我什至使用正确的函数来运行带有用户输入的嵌入式 Python。

【问题讨论】:

  • 你忽略了每个函数的返回值。这意味着您无法检测到错误,也意味着您根本无法使用已编译的代码(并为此泄漏内存)。我怀疑完全空的字典同时阻止 print 工作。
  • @DavisHerring - 关于完全空的字典:yes it will be missing print
  • Py_CompileString 返回编译的代码对象作为其返回值...

标签: python c++ python-c-api


【解决方案1】:

您的程序中不需要 C 标签。您的问题仅与 C++ 代码有关。首先,

string input;

cin >> input;

读取一个以空格分隔的单词,与 C 中的scanf("%s", input); 不同。您需要使用

getline(cin, input);

下一个问题是input.data() need not be zero-terminated。您必须使用 input.c_str()

最后:您必须始终检查您调用的每个 Python API 函数的返回值。没有允许的快捷方式。

【讨论】:

  • data() 自 C++11 以来已被空终止。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-03
  • 2020-12-23
  • 2011-05-16
相关资源
最近更新 更多