【问题标题】:compile error gcc with Python.h使用 Python.h 编译错误 gcc
【发布时间】:2013-01-10 14:30:32
【问题描述】:

我正在尝试将 python 嵌入到 c++ 中,并且我一直在使用一些示例代码。我正在使用 boost python 解释器,它工作正常,但现在我似乎无法编译一些使用 Python.h 的 c++ 代码。我收到一个错误,似乎是未正确引用库(此代码应该可以正常工作,因为它是直接从http://www.codeproject.com/Articles/11805/Embedding-Python-in-C-C-Part-I 复制而来的)。我尝试了许多编译标志。任何帮助都感激不尽!谢谢:)

以下是一个示例和我收到的错误:

g++ -Wall -o call_function call_function.c

call_function.c: In function âint main(int, char**)â:
call_function.c:61:56: warning: format â%dâ expects argument of type âintâ, but argument 2 has type âlong intâ [-Wformat]
/tmp/ccAUMMHm.o: In function `main':
call_function.c:(.text+0x2a): undefined reference to `Py_Initialize'
call_function.c:(.text+0x3d): undefined reference to `PyString_FromString'
call_function.c:(.text+0x4d): undefined reference to `PyImport_Import'
call_function.c:(.text+0x5d): undefined reference to `PyModule_GetDict'
call_function.c:(.text+0x7b): undefined reference to `PyDict_GetItemString'
call_function.c:(.text+0x8b): undefined reference to `PyCallable_Check'
call_function.c:(.text+0xb2): undefined reference to `PyTuple_New'
call_function.c:(.text+0xe5): undefined reference to `PyInt_FromLong'
call_function.c:(.text+0xf5): undefined reference to `PyErr_Print'
call_function.c:(.text+0x118): undefined reference to `PyTuple_SetItem'
call_function.c:(.text+0x13f): undefined reference to `PyObject_CallObject'
call_function.c:(.text+0x195): undefined reference to `PyObject_CallObject'
call_function.c:(.text+0x1ac): undefined reference to `PyInt_AsLong'
call_function.c:(.text+0x1fd): undefined reference to `PyErr_Print'
call_function.c:(.text+0x204): undefined reference to `PyErr_Print'
call_function.c:(.text+0x279): undefined reference to `Py_Finalize'
collect2: ld returned 1 exit status

以下是c++代码

// call_function.c - A sample of calling python functions from C code
//
#include "/usr/include/python2.6/Python.h"

int main(int argc, char *argv[])
{
    int i;
    PyObject *pName, *pModule, *pDict, *pFunc, *pArgs, *pValue;
    if (argc < 3)
    {
        printf("Usage: exe_name python_source function_name\n");
        return 1;
    }
    // Initialize the Python Interpreter
    Py_Initialize();
    // Build the name object
    pName = PyString_FromString(argv[1]);
    // Load the module object
    pModule = PyImport_Import(pName);
    // pDict is a borrowed reference
    pDict = PyModule_GetDict(pModule);
    // pFunc is also a borrowed reference
    pFunc = PyDict_GetItemString(pDict, argv[2]);
    if (PyCallable_Check(pFunc))
    {
        // Prepare the argument list for the call
        if( argc > 3 )
        {
                pArgs = PyTuple_New(argc - 3);
                for (i = 0; i < argc - 3; i++)
                {
                    pValue = PyInt_FromLong(atoi(argv[i + 3]));
                    if (!pValue)
                    {
                        PyErr_Print();
                        return 1;
                    }
                    PyTuple_SetItem(pArgs, i, pValue);
                }
                pValue = PyObject_CallObject(pFunc, pArgs);
                if (pArgs != NULL)
                {
                    Py_DECREF(pArgs);
                }
        } else
        {
                pValue = PyObject_CallObject(pFunc, NULL);
        }
        if (pValue != NULL)
        {
            printf("Return of call : %d\n", PyInt_AsLong(pValue));
            Py_DECREF(pValue);
        }
        else
        {
            PyErr_Print();
        }
    } else
    {
        PyErr_Print();
    }

    // Clean up
    Py_DECREF(pModule);
    Py_DECREF(pName);
    // Finish the Python Interpreter
    Py_Finalize();
    return 0;
}

以下是python脚本:

'''py_function.py - Python source designed to '''
'''demonstrate the use of python embedding'''

def multiply():
    c = 12345*6789
    print 'The result of 12345 x 6789 :', c
    return c

【问题讨论】:

    标签: c++


    【解决方案1】:

    你需要用-lpython2.6编译。

    编译器找不到libpythonX.Y.so 中定义的python 函数。要告诉它使用该库,您需要添加-lpythonX.Y。由于您的 Python 版本是 2.6,因此您需要使用 -lpython2.6

    你得到像(.text+0xf00) 这样的事实告诉你这是一个链接器问题,这意味着你的代码本身很好。问题只是一些功能没有完全定义。这意味着,编译器在编译时(从头文件)知道原型(即返回类型和参数值),但它不知道实际代码在哪里。这取决于链接器来解决这个问题,它无法通过魔法知道它会在哪里找到必要的功能。

    【讨论】:

    • 感谢@Jonas Wielicki 的帮助。我知道我必须加载 python2.6,但我认为通过输入应该没问题的路径。我似乎找不到 pythonX.Y。我实际上尝试通过以下方式进行编译: g++ -Wall -I/usr/include/python2.6 -lpython2.6 -lpythonX.Y -o call_function call_function.c 但错误是它找不到 /usr/bin/ld : -lpythonX.是的
    • -lpythonX.Y 只是一个例子。不要将它添加到您的命令行中。 X 和 Y 是 python 版本号的占位符。此外,不要混淆源(使用-I… 添加路径)和必须使用-l 传递给链接器的动态库。也许您想了解compilerslinkers 之间的区别。
    • 非常感谢乔纳斯的帮助。你能解释一下 -I 做什么和 -l 做什么吗?我现在明白,如果我没记错的话,-l 会将库添加到链接器,但是 -I 标志有什么作用?
    • 嗯...我的标志中已经有-lpython2.7,但我有一个相同的错误。
    • @PatrizioBertoni 在文档中快速搜索 Python 2.7 与 3.5 显示 PyInt_AsLong 在 3.5 中不存在。
    猜你喜欢
    • 1970-01-01
    • 2014-03-08
    • 2016-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多