0

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

0

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.

Sign up to request clarification or add additional context in comments.

3 Comments

I have updated the code as per your suggestion. However, I can import intzoo but cannot import intanim namespace. I have pasted the error.
@EjazAhmed the content of the question shouldn't be modified, now what I put in my answer doesn't make sense as your question already contain that. Also publish updates rather at the bottom than at the top of the question.
changed accordingly. Do you have any idea on new error I have pasted above?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.