将`__str__`方法添加到Boost Python C++类时构建问题

Ric*_*ard 18 python boost-python

我已经开始尝试使用boost python并遇到问题.我试图将一个C++类暴露给python,这没有任何问题.但我似乎无法实现__str__类的功能而不会出现我不明白的构建错误.

我正在使用boostpro的boost 1_42 prebuild.我使用cmake和vs2010编译器构建库.

我有一个非常简单的设置.头文件(tutorial.h)如下所示:

#include <iostream>
namespace TestBoostPython{
    class TestClass {
        private:
            double m_x;
        public:
            TestClass(double x);
            double Get_x() const;
            void Set_x(double x);
    };
    std::ostream &operator<<(std::ostream &ostr, const TestClass &ts);
};
Run Code Online (Sandbox Code Playgroud)

和相应的cpp文件看起来像:

#include <boost/python.hpp>
#include "tutorial.h"

using namespace TestBoostPython;

TestClass::TestClass(double x)
{
    m_x = x;
}

double TestClass::Get_x() const
{
    return m_x;
}
void TestClass::Set_x(double x)
{
    m_x = x;
}

std::ostream &operator<<(std::ostream &ostr, const TestClass &ts)
{
    ostr << ts.Get_x() << "\n";
    return ostr;
}

BOOST_PYTHON_MODULE(testme)
{
using namespace boost::python;
class_<TestClass>("TestClass", init<double>())
    .add_property("x", &TestClass::Get_x, &TestClass::Set_x)
    .def(str(self))
    ;
}
Run Code Online (Sandbox Code Playgroud)

CMakeLists.txt如下所示:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8)

project (testme)

FIND_PACKAGE( Boost REQUIRED )
FIND_PACKAGE( Boost COMPONENTS python REQUIRED )
FIND_PACKAGE( PythonLibs REQUIRED )

set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREAD ON)

INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
INCLUDE_DIRECTORIES ( ${PYTHON_INCLUDE_PATH} )

add_library(testme SHARED tutorial.cpp)
target_link_libraries(testme ${Boost_PYTHON_LIBRARY})
target_link_libraries(testme ${PYTHON_LIBRARY}
Run Code Online (Sandbox Code Playgroud)

我得到的构建错误如下:

Compiling...
tutorial.cpp
    C:\Program Files (x86)\boost\boost_1_42\boost/python/def_visitor.hpp(31) : error C2780: 'void boost::python::api::object_operators::visit(ClassT &,const char *,const boost::python::detail::def_helper &) const' : expects 3 arguments - 1 provided
    with
    [
        U=boost::python::api::object
    ]
    C:\Program Files (x86)\boost\boost_1_42\boost/python/object_core.hpp(203) : see declaration of 'boost::python::api::object_operators::visit'
    with
    [
        U=boost::python::api::object
    ]
    C:\Program Files (x86)\boost\boost_1_42\boost/python/def_visitor.hpp(67) : see reference to function template instantiation 'void boost::python::def_visitor_access::visit,classT>(const V &,classT &)' being compiled
    with
    [
        DerivedVisitor=boost::python::api::object,
        classT=boost::python::class_,
        V=boost::python::def_visitor
    ]
    C:\Program Files (x86)\boost\boost_1_42\boost/python/class.hpp(225) : see reference to function template instantiation 'void boost::python::def_visitor::visit>(classT &) const' being compiled
    with
    [
        DerivedVisitor=boost::python::api::object,
        W=TestBoostPython::TestClass,
        classT=boost::python::class_
    ]
    .\tutorial.cpp(29) : see reference to function template instantiation 'boost::python::class_ &boost::python::class_::def(const boost::python::def_visitor &)' being compiled
    with
    [
        W=TestBoostPython::TestClass,
        U=boost::python::api::object,
        DerivedVisitor=boost::python::api::object
    ]
Run Code Online (Sandbox Code Playgroud)

谁有任何关于什么是错误的想法?如果我从包装器代码中删除.def(str(self))部分,一切都编译得很好,并且该类可以从python中使用.我非常感谢你的帮助.

谢谢Rickard

编辑:忘了一个const

Jam*_*mes 29

我最近遇到了这个问题; 有效的解决方案是明确解决strself在这一行:

.def(str(self))
Run Code Online (Sandbox Code Playgroud)

这样就变成了:

.def(self_ns::str(self_ns::self))
Run Code Online (Sandbox Code Playgroud)

我不知道为什么这是必要的,(知道一些在boost python中发生的重载分辨率并发症,它可能就在那里......)但它对我有用:)

  • 有一个 boost::python::str 和一个 boost::python::self_ns::str,它们是非常不同的东西。这是必要的,因为如果您的代码使用了 `using boost::python`(可能会有很多),编译器会发现前者,这很容易混淆它。 (4认同)
  • 精彩!非常感谢.我喜欢boost :: python但是当这样的事情发生时,我认为在Python C-API中手动包装对象可能更容易.我永远不会自己找到这个解决方案.再次感谢. (2认同)

And*_*ost 11

我碰到了同样的事情.添加此行(而不是限定str和self)也有效:

using self_ns::str;
Run Code Online (Sandbox Code Playgroud)