PyObject_GetAttrString C++ 函数返回 NULL:无法从 C++ 调用 Python 函数

5 投票
3 回答
4755 浏览
提问于 2025-04-18 10:24

我刚开始用Python和C++一起工作,有点困惑,为什么我不能从C++调用Python中的函数。

这是我现在在C++中的测试代码:

      #include <iostream>
      #include <Python.h>
      using namespace std;

      int main()
      {
             Py_Initialize();
             PyObject* myModuleString = PyString_FromString("test");
             PyObject* myModule       = PyImport_Import(myModuleString);

             if( myModule )
             {
                      PyObject* myFunction     = PyObject_GetAttrString(myModule, "Hello");
                      if( myFunction )
                      {
                             PyEval_CallObject( myFunction, NULL );
                      }
                      else
                      {
                             fprintf( stderr, "myFunction is NULL" );
                      }
             }
             else
             {
                      fprintf( stderr, "myModule is NULL" );
             }

             Py_Finalize();
             cin.get();
             return 0;
      }

这是我的test.py Python代码:

      import sys

      def Hello():
            print "Hello, world!"

之前我做了一个更复杂的测试,但遇到了一个问题,PyObject_GetAttrString返回了NULL,所以我想做一个简单的测试,结果在调用PyObject_GetAttrString后还是得到了NULL。根据我的理解,PyObject_GetAttrString可以获取到函数的PyObject*,然后我再调用它,所以如果那里返回NULL,基本上就意味着我无法调用这个函数。

另外,我确实查看了https://docs.python.org/2.7/,甚至测试了https://docs.python.org/release/2.6.5/extending/embedding.html#pure-embedding中第5.3步给出的示例(我使用的是2.7.7,因为我打算和3ds Max集成)。结果在使用PyObject_GetAttrString时还是遇到了同样的问题。

我猜这可能是我在C++或Python代码中遗漏了什么简单的错误或步骤。

3 个回答

0

我之前也遇到过类似的问题。我发现我传给Python的字符串里的空格有点问题。根据我的观察,你的打印语句里有6个空格,而不是4个。你可以回去检查一下,看看问题是不是就解决了。

2

我也遇到过同样的问题。虽然 test.pymycode.c 在同一个文件夹里(/home/user/python/example),但我需要在 Py_Initialize(); 之后添加一个路径引用,像下面这一行这样:

PyRun_SimpleString ("import sys; sys.path.insert(0, '/home/user/python/spp')");*

把 /home... 替换成你自己的路径。

我之前的代码没有那一行,但 PyImport_Import 能正常工作,而 PyObject_GetAttrString 就不行。这让我很困惑,"别问我,我也不知道 - Ozzy"。

3

把Python脚本的名字从 test.py 改成其他任何名字对我来说有效。

撰写回答