【问题标题】:Error in boost-python nested namespace exporting codeboost-python 嵌套命名空间导出代码中的错误
【发布时间】:2019-02-01 22:36:28
【问题描述】:

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

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

动物园.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);
}

动物.h:

namespace extanim
{
namespace intanim
{
class animal
{
public:
const std::string hello_animal();     
const std::string getname_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

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

导入 pyintf 回溯(最近一次通话最后): 文件“”,第 1 行,在 ImportError:./pyintf.so:未定义符号:_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'

【问题讨论】:

    标签: python boost-python


    【解决方案1】:

    在您的 cpp 文件中,您需要将类方法的定义放在适当的命名空间中,而不是 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 时会出错,因为没有定义此类名称的范围。

    【讨论】:

    • 我已根据您的建议更新了代码。但是,我可以导入 intzoo 但不能导入 intanim 命名空间。我已经粘贴了错误。
    • @EjazAhmed 不应修改问题的内容,现在我在回答中的内容没有意义,因为您的问题已经包含该内容。还要在问题底部而不是在问题顶部发布更新。
    • 相应地改变了。您对我在上面粘贴的新错误有任何想法吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-06
    • 1970-01-01
    • 2021-10-26
    • 2011-03-13
    • 1970-01-01
    • 2012-07-23
    • 1970-01-01
    相关资源
    最近更新 更多