Error in boost-python nested namespace exporting code

匿名 (未验证) 提交于 2019-12-03 01:41:02

问题:

I am working on exporting two classes class zoo (extzoo and intzoo namespaces), class animal (extanim and intanim namespaces)" methods which are defined within two level nested namespaces. I want to expose these methods to Python interpreter from where I can access them. I have written code, created a shared library but when I import it into a python I get an error. I will appreciate your guidance on this.

I have followed the answer given on the following link in similar context of exposing C++ nested namespaces: 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)         ; }

I have compiled the above code using following command:

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

I am getting error on importing the shared library

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

+++++++++++++++++++++++++++Update+++++++++++++++++++++++++++++++++

I have changed the code based on @doqtor suggestion. However, now I cannot import in Python a namespace 'intanim' defined in one file while other can 'intzoo'. As you may see below.

>>> 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' 

回答1:

In your cpp files you need to put definitions of the class methods inside the appropriate namespaces instead of using namespace ... declarations. For example for zoo.cpp that will be:

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

--------------------------------------------- Update ------------------------------------------------------------------------------

Add scope in c++ code to separate definitions of python scope using {}:

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  }

And the test:

>>> 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 >>> 

Note that error on importing extanim is expected as there isn't scope of such name defined.



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!