c++ 未声明的标识符:PyUnicode_DecodeFSDefault

dy1byipe  于 11个月前  发布在  其他
关注(0)|答案(4)|浏览(143)

我试着从Python网站https://docs.python.org/3/extending/embedding.html编译示例代码。除了下面这行之外,一切都很好:

pName = PyUnicode_DecodeFSDefault(argv[1]);

字符串
我在MacOS El Captain上安装了Python 3.6。我的make文件看起来像这样:

call_function:     call_function.o        
    gcc -o call_function call_function.o -export-dynamic -L/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/config-3.6m-darwin -lpython3.6m -lpthread -lm -ldl -lutil

call_function.o:call_function.cpp    
    gcc -c call_function.cpp -I/Library/Frameworks/Python.framework/Versions/3.6/include/python3.6m


当我编译C++代码时,我得到以下错误:

gcc -c call_function.cpp -I/Library/Frameworks/Python.framework/Versions/3.6/include/python3.6m
call_function.cpp:16:13: error: use of undeclared identifier    'PyUnicode_DecodeFSDefault'
pName = PyUnicode_DecodeFSDefault(argv[1]);
        ^
1 error generated.


有人知道如何修复上述错误吗?我将非常感谢您的帮助。
下面是完整的示例代码:

#include <Python/Python.h>
#include <Python/unicodeobject.h>

int main(int argc, char *argv[])
{
PyObject *pName, *pModule, *pDict, *pFunc;
PyObject *pArgs, *pValue;
int i;

if (argc < 3) {
    fprintf(stderr,"Usage: call pythonfile funcname [args]\n");
    return 1;
}

Py_Initialize();
pName = PyUnicode_DecodeFSDefault(argv[1]);
// pName = PyUnicode_FromString(argv[1]);  <-- also gives me an error

/* Error checking of pName left out */

pModule = PyImport_Import(pName);
Py_DECREF(pName);

if (pModule != NULL) {
    pFunc = PyObject_GetAttrString(pModule, argv[2]);
    /* pFunc is a new reference */

    if (pFunc && PyCallable_Check(pFunc)) {
        pArgs = PyTuple_New(argc - 3);
        for (i = 0; i < argc - 3; ++i) {
            pValue = PyLong_FromLong(atoi(argv[i + 3]));
            if (!pValue) {
                Py_DECREF(pArgs);
                Py_DECREF(pModule);
                fprintf(stderr, "Cannot convert argument\n");
                return 1;
            }
            /* pValue reference stolen here: */
            PyTuple_SetItem(pArgs, i, pValue);
        }
        pValue = PyObject_CallObject(pFunc, pArgs);
        Py_DECREF(pArgs);
        if (pValue != NULL) {
            printf("Result of call: %ld\n", PyLong_AsLong(pValue));
            Py_DECREF(pValue);
        }
        else {
            Py_DECREF(pFunc);
            Py_DECREF(pModule);
            PyErr_Print();
            fprintf(stderr,"Call failed\n");
            return 1;
        }
    }
    else {
        if (PyErr_Occurred())
            PyErr_Print();
        fprintf(stderr, "Cannot find function \"%s\"\n", argv[2]);
    }
    Py_XDECREF(pFunc);
    Py_DECREF(pModule);
}
else {
    PyErr_Print();
    fprintf(stderr, "Failed to load \"%s\"\n", argv[1]);
    return 1;
}
Py_Finalize();
return 0;
}

ikfrs5lh

ikfrs5lh1#

我发现了问题所在。include <Python/Python.h>语句实际上链接到了/System/Library/Frameworks/Python.framework/Versions/Current,目前是Python2.7。我已经在Mac上安装了Python 3.6,甚至我在make文件中包含了/Library/Frameworks/Python.framework/Versions/3.6/include/python3.6m,它仍然引用MacOS的Python 2.7文件夹中的Python.h文件。我试图将Current的符号链接更改为新的3.6文件夹,它不让我做修改。有人知道如何修改Python 2.7当前文件夹的符号链接,这样我的gcc就可以在Python 3.6文件夹中查找Python.h了吗?

m1m5dgzv

m1m5dgzv2#

这是一个很长的时间,因为这个问题被张贴,但我想出的解决方案如下:

char * full_cls_name = argv[1];
Py_Initialize();
pName = PyString_FromString(full_cls_name);

字符串
你还应该检查argv[1]是否存在。

uinbv5nw

uinbv5nw3#

我就是这么做的。

gcc -o call  $(python3-config --cflags --embed) multiply_embed.c $(python3-config --ldflags --embed)

字符串
我从this post得到了答案-答案来自Ciro Pilli утлер。
在运行代码时,我还得到了模块未找到错误,这是通过在zshrc文件中设置PYTHONPATH变量来克服的,如下所述。

9wbgstp7

9wbgstp74#

由于版本不匹配,我在MacOS上得到了这个错误。所以基本上我已经通过homebrew以及我们可以从python.org下载的.pkg文件安装了python。Hombrew版本是3.11,而前者是3.9
在Mac上,默认情况下,cmake在以下目录中查找

/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/Current

字符串
当通过homebrew安装时,它将python安装在以下目录中

/opt/homebrew/Cellar/[email protected]/3.11.6_1/Frameworks/Python.framework/Versions/3.11


所以我按照这些步骤象征性地链接brew版本作为默认的python可执行文件。

  • 删除较旧的Python 3安装
sudo rm -rf /Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9
 sudo rm /Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/Current

  • 向Homebrew Python 3.11版本添加符号链接
sudo ln -s /opt/homebrew/Cellar/[email protected]/3.11.6_1/Frameworks/Python.framework/Versions/3.11 /Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.11
sudo ln -s /Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.11 /Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/Current

相关问题