boost-python 嵌套命名空间导出代码时出错

Error in boost-python nested namespace exporting code

我正在努力导出两个 classes class 动物园(extzoo 和 intzoo 命名空间),class 动物(extanim 和 intanim 命名空间)”方法是 在两层嵌套的命名空间中定义。我想公开这些方法 Python 解释器,我可以从那里访问它们。我写过代码, 创建了一个共享库,但是当我将其导入 python 时出现错误。 我将感谢您对此的指导。

我在类似的上下文中遵循了以下 link 给出的答案 公开 C++ 嵌套命名空间:create boost-python nested namespace

zoo.h:

namespace extzoo
{
namespace intzoo
{
class zoo
{
public:
const std::string hello_zoo();
const std::string getname_zoo();
};
}
}      

zoo.cpp:

using namespace extzoo;
using namespace intzoo;

const std::string zoo::hello_zoo() {
     return std::string("hello, zoo");
}

const std::string zoo::getname_zoo() {
      std::string input;
      std::cout<<"Please enter your favorit zoo name: ";
      std::getline(std::cin,input);
      return std::string("Your favorit zoo name is: ").append(input);
}

animal.h:

namespace extanim
{
namespace intanim
{
class animal
{
public:
const std::string hello_animal();     
const std::string getname_animal();
};
}
}

animal.cpp:

using namespace extanim;
using namespace intanim;

const std::string animal::hello_animal() {
      return std::string("hello, animal");
}
const std::string animal::getname_animal() {
      std::string input;
      std::cout<<"Please enter your favorit animal name: ";
      std::getline(std::cin,input);
      return std::string("Your favorit animal name is: ").append(input);
     }

pyintf.cpp:

// An established convention for using boost.python.
using namespace boost::python;
//user defined ns
using namespace extzoo::intzoo;
using namespace extzoo;
using namespace extanim::intanim;
using namespace extanim;

class DummyZoo{};
class DummyAnimal{};

BOOST_PYTHON_MODULE(pyintf) {

    scope intzoo
    = class_<DummyZoo>("intzoo");

    class_<extzoo::intzoo::zoo>("zoo")
    // Expose the function hello_zoo().
       .def("hello_zoo", &extzoo::intzoo::zoo::hello_zoo)
        // Expose the function getname_zoo().    
        .def("getname_zoo", &extzoo::intzoo::zoo::getname_zoo)
        ;



    scope intanim
        = class_<DummyAnimal>("intanim"); 

    class_<extanim::intanim::animal>("animal")
        // Expose the function hello_animal().
        .def("hello_animal", &extanim::intanim::animal::hello_animal)
        // Expose the function getname_animal().    
        .def("getname_animal", &extanim::intanim::animal::getname_animal)
        ;
}

我使用以下命令编译了上面的代码:

g++ -shared -o pyintf.so -fPIC pyintf.cpp zoo.h zoo.cpp animal.h animal.cpp -lboost_python -lpython2.7 -I/usr/include/python2.7

我在导入共享库时遇到错误

import pyintf Traceback (most recent call last): File "", line 1, in ImportError: ./pyintf.so: undefined symbol: _ZN7extanim7intanim6animal14getname_animalEv

++++++++++++++++++++++++++++更新++++++++++++++++++++++++++++++++

我已经根据@doqtor 的建议更改了代码。但是,现在我无法在 Python 中导入在一个文件中定义的命名空间 'intanim',而其他文件可以 'intzoo'。如下所示。

>>> import pyintf 
>>> pyintf.intanim.animal().hello_animal()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'intanim'
>>> from pyintf import intanim
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: cannot import name intanim
>>> from pyintf import extanim
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: cannot import name extanim
>>> from pyintf import intzoo
>>> intzoo.zoo().hello_zoo()
'hello, zoo'

在您的 cpp 文件中,您需要将 class 方法的定义放在适当的命名空间中,而不是 using namespace ... 声明。例如 zoo.cpp 将是:

namespace extzoo
{
namespace intzoo
{
const std::string zoo::hello_zoo() {
// ... code
}

const std::string zoo::getname_zoo() {
// ... code
}
}
}

-------------------------------------------- 更新 -------------------------------------- --------------------------------------

在 C++ 代码中添加范围以使用 {}:

分隔 python 范围的定义
BOOST_PYTHON_MODULE(pyintf) { // set scope to pyintf

{
    scope intzoo
    = class_<DummyZoo>("intzoo"); // define and set scope to pyintf.intzoo

    class_<extzoo::intzoo::zoo>("zoo")
    // Expose the function hello_zoo().
       .def("hello_zoo", &extzoo::intzoo::zoo::hello_zoo)
        // Expose the function getname_zoo().    
        .def("getname_zoo", &extzoo::intzoo::zoo::getname_zoo)
        ;
} // revert scope to pyintf


{
    scope intanim
        = class_<DummyAnimal>("intanim"); // define and set scope to pyintf.intanim

    class_<extanim::intanim::animal>("animal")
        // Expose the function hello_animal().
        .def("hello_animal", &extanim::intanim::animal::hello_animal)
        // Expose the function getname_animal().    
        .def("getname_animal", &extanim::intanim::animal::getname_animal)
        ;
} // revert scope to pyintf

}

测试:

>>> import pyintf
>>> dir(pyintf)
['__doc__', '__file__', '__name__', '__package__', 'intanim', 'intzoo']
>>> pyintf.intanim.animal().hello_animal()
'hello, animal'
>>> from pyintf import intanim
>>> from pyintf import extanim
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: cannot import name extanim
>>> from pyintf import intzoo
>>> 

请注意,导入 extanim 时会出错,因为没有定义此类名称的范围。