Boost Python def成员函数,它以self为唯一参数调用静态函数

时间:2016-02-09 05:07:41

标签: python c++ boost

因此,我已经开始将GLM的许多功能包装到我的嵌入式Python模块中。

GLM的一个好处是它将所有它的典型矢量数学函数(lengthnormalize等)定义为独立的静态函数。这在编写C ++时非常有用,但在尝试将此功能作为类定义的一部分包装时,它会引发一些麻烦。

我想在我的len类上调用Vec3F并让length调用正确的重载,同时将self作为第一个也是唯一的参数。 Boost.Python文档相当不透明,并没有很多例子,所以我甚至都不知道这是否可行。

lengthvec2结构中实现vec3函数是不可能的,因为这些结构在另一个项目中;我必须按原样处理结构。

非常感谢任何帮助!

Python接口

Vec3F v
v.x = 1.0
v.y = 1.0
v.z = 1.0
print len(v) # should print 1.732050...

模块定义

template<typename T>
struct vec2
{
    T x;
    T y;
};

template<typename T>
struct vec3
{
    T x;
    T y;
    T z;
};

template<typename T>
float length(vec2& v)
{
    return sqrt(v.x * v.x + v.y * v.y);
}

template<typename T>
float length(vec3& v)
{
    return sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
}

BOOST_PYTHON_MODULE(naga)
{
    class_<vec2<float>, "Vec2F")
        .def("x", &vec2<float>::x)
        .def("y", &vec2<float>::y)
        .def("__len__", /* ??? */); // not sure what needs to be here!

    class_<vec3<float>, "Vec3F")
        .def("x", &vec2<float>::x)
        .def("y", &vec2<float>::y)
        .def("__len__", /* ??? */);  // not sure what needs to be here!
}

1 个答案:

答案 0 :(得分:1)

您将需要一个包装器类,但仍然__len__不会返回正确的结果,因为返回值在内部转换为整数(我怀疑__len__必须始终返回整数值)。 因此,您需要将其公开为len以获得正确的浮点返回值。

namespace bp = boost::python;

template<typename T>
struct vec2
{
    T x;
    T y;
};

template<typename T>
struct vec3
{
    T x;
    T y;
    T z;
};

template <typename T>
struct vec2_wrapper : vec2<T>
{
    float length()
    {
        return sqrt(x * x + y * y);
    }
};

template <typename T>
struct vec3_wrapper : vec3<T>
{
    float length()
    {
        return sqrt(x * x + y * y + z * z);
    }
};

BOOST_PYTHON_MODULE(naga)
{
    bp::class_ < vec2_wrapper<float> >("Vec2F")
        .def_readwrite("x", &vec2_wrapper<float>::x)
        .def_readwrite("y", &vec2_wrapper<float>::y)
        .def("__len__", &vec2_wrapper<float>::length)
        .def("len", &vec2_wrapper<float>::length)
        ;

    bp::class_ < vec3_wrapper<float> >("Vec3F")
        .def_readwrite("x", &vec3_wrapper<float>::x)
        .def_readwrite("y", &vec3_wrapper<float>::y)
        .def_readwrite("z", &vec3_wrapper<float>::z)
        .def("__len__", &vec3_wrapper<float>::length)
        .def("len", &vec3_wrapper<float>::length)
        ;
}

Python测试:

import naga as vec

v = vec.Vec3F()
v.x = 1.0
v.y = 1.0
v.z = 1.0
print "len(v):", len(v)
print "v.len():", v.len()

输出:

len(v): 1
v.len(): 1.73205077648