在C中嵌入Python以处理配置文件

1 投票
2 回答
1227 浏览
提问于 2025-04-16 05:46

我正在尝试把Python嵌入到C语言中,以便用它来做配置:

如果我这样做:

/******************************************************************************
* 
* Embeding Python Example
*
* To run: 
*   gcc -c test.c -o test.o -I"C:/Python25/include"
*   gcc -o test.exe test.o -L"C:/Python25/libs" -lpython25
*   test.exe
*
******************************************************************************/

#include <Python.h>

int main(int argc, char *argv[])
{
    PyObject *run;
    PyObject *globals = PyDict_New();
    PyObject *locals = PyDict_New();

    Py_Initialize();

    run = PyRun_String("from time import time,ctime\n"
                       "print 'Today is',ctime(time())\n"
                        "test = 5\n"
                        "print test\n", Py_file_input, globals, locals);


    Py_Finalize();
    return 0;
}

我收到了来自微软Visual C++运行时的错误,错误信息是:

Exception exceptions.ImportError: '__import__ not found' in 'garbage collection' ignored
Fatal Python error: unexpected exception during garbage collection

我哪里做错了呢?

2 个回答

0

在你初始化Python引擎之前,你已经创建了两个Python对象。

而且,这样做也太傻了。其实有很多适合C语言用的JSON解析器。

2

你做错的事情正是我之前也犯过的错误。

你把自己的 globals 字典初始化成了空的。这就意味着像 __import__ 这样的东西在当前的范围内是没有定义的。

在你简单的例子中,你可以把

run = PyRun_String("from time import time,ctime\n"
                   "print 'Today is',ctime(time())\n"
                    "test = 5\n"
                    "print test\n", Py_file_input, globals, locals);

替换成

PyRun_SimpleString("from time import time,ctime\n"
                   "print 'Today is',ctime(time())\n"
                   "test = 5\n"
                   "print test\n");

你可能还想完全去掉 globalslocals

如果我找到访问 默认 globals 字典的方法,我会在这里添加评论或编辑。

编辑: PyRun_SimpleStringFlags(Python 2.7.3)的实现看起来是这样的:

int PyRun_SimpleStringFlags(const char *command, PyCompilerFlags *flags)
{
    PyObject *m, *d, *v;
    m = PyImport_AddModule("__main__");
    if (m == NULL)
        return -1;
    d = PyModule_GetDict(m);
    v = PyRun_StringFlags(command, Py_file_input, d, d, flags);
    ...

所以,要获取 默认 globals 字典,你需要导入 __main__ 并获取 它的 字典。这将包含所有默认的内置函数等等。

撰写回答