我正在为我的项目编写python包装器,它使用Eigen进行数学计算。在测试基本操作之后,在python中创建的特征对象总是返回不正确的结果。当我没有使用Eigen来尊重数据对齐时,这通常发生在我身上。这是通过使用Eigen :: aligned_allocator分配特征对象来解决的。如何告诉boost使用Eigen :: aligned_allocator分配特征对象?
这是一个简单的测试:
C ++
using namespace boost::python;
using namespace Eigen;
class_<Isometry3d>("Isometry3d", init<>())
.def("__str__", make_function(IsometryToStr))
.def_readonly("Identity", Isometry3d::Identity())
;
IsometryToStr函数只使用运算符&lt;&lt;由Eigen定义。
的Python:
a = Isometry3d.Identity
print a
我们希望它能打印单位矩阵,但结果总是不同。
答案 0 :(得分:1)
要控制C ++类型的分配,请使用make_constructor
将工厂函数注册为Python对象的构造函数。通常,自定义分配也意味着自定义释放,在这种情况下,boost::shared_ptr
可用于管理对象的生命周期并调用自定义解除分配策略。这个answer会详细介绍,但这里有一个基本自定义分配器的完整示例。
#include <cstdlib>
#include <boost/python.hpp>
#include <boost/shared_ptr.hpp>
/// @brief Basic custom allocator.
template <typename T>
class custom_allocator
{
public:
typedef size_t size_type;
typedef T* pointer;
typedef T value_type;
public:
pointer allocate(size_type num, const void* hint = 0)
{
std::cout << "custom_allocator::allocate()" << std::endl;
return reinterpret_cast<pointer>(
std::malloc(num * sizeof(value_type)));
}
void deallocate(pointer p, size_type num)
{
std::cout << "custom_allocator::deallocate()" << std::endl;
std::free(p);
}
};
/// @brief Example class.
class foo
{
public:
foo() { std::cout << "foo()" << std::endl; }
~foo() { std::cout << "~foo()" << std::endl; }
void action() { std::cout << "foo::action()" << std::endl; }
};
/// @brief Allocator for foo.
custom_allocator<foo> foo_allocator;
/// @brief Destroy a foo object.
void destroy_foo(foo* p)
{
p->~foo(); // Destruct.
foo_allocator.deallocate(p, 1); // Deallocate.
}
/// @brief Factory function to create a foo object.
boost::shared_ptr<foo> create_foo()
{
void* memory = foo_allocator.allocate(1); // Allocate.
return boost::shared_ptr<foo>(
new (memory) foo(), // Construct in allocated memory.
&destroy_foo); // Use custom deleter.
}
BOOST_PYTHON_MODULE(example) {
namespace python = boost::python;
// Expose foo, that will be managed by shared_ptr, and transparently
// constructs the foo via a factory function to allow for a custom
// deleter to use the custom allocator.
python::class_<foo, boost::shared_ptr<foo>,
boost::noncopyable>("Foo", python::no_init)
.def("__init__", python::make_constructor(&create_foo))
.def("action", &foo::action)
;
}
用法:
>>> import example
>>> f = example.Foo()
custom_allocator::allocate()
foo()
>>> f.action()
foo::action()
>>> f = None
~foo()
custom_allocator::deallocate()