Boost::python 和 Eigen/dense 造成分段错误

Boost::python and Eigen/dense create a segmentation fault

我想在这样的结构中使用 Eigen/dense 对象:

#include <boost/python.hpp>
#include <Eigen/Dense>
#include <iostream>
#include <vector>

struct data_t {
    Eigen::Matrix2f matrix;
    //std::vector<float> matrix;
};

data_t init_data() {
    data_t result;
    result.matrix(0, 0) = 1.0f;
    result.matrix(0, 1) = 2.0f;
    result.matrix(1, 0) = 3.0f;
    result.matrix(1, 1) = 4.0f;
    //result.matrix.push_back(1.0f);
    //result.matrix.push_back(2.0f);
    //result.matrix.push_back(3.0f);
    //result.matrix.push_back(4.0f);
    return result;
}


BOOST_PYTHON_MODULE(python_test) {

    boost::python::class_<data_t>("DataType")
        .def("from_init", &init_data)
        .staticmethod("from_init")
    ;
}

python 代码如下所示:

import python_test

def init_data():
    return python_test.DataType.from_init()

sample = init_data()

执行导致分段错误。我的问题是:为什么?如果我用 std::vector 替换 Eigen 对象,代码运行正常。

问题是 data_t 包含一个 Eigen 期望对齐的矩阵,但 Boost::Python 无法在对齐的内存上分配。

最简单的解决方法是仅为此禁用对齐(制作一个 typedef,如果您经常使用它):

struct data_t {
    Eigen::Matrix<float, 2, 2, Eigen::DontAlign> matrix;
};

或者,通过使用 -D EIGEN_MAX_STATIC_ALIGN_BYTES=0(在最新的 Eigen 版本上)或 -D EIGEN_DONT_ALIGN_STATICALLY(对于较旧的 Eigen 版本)进行编译来一起禁用静态对齐。

实际上,如果 Boost::Python 使用 operator::new 分配其对象,以下方法也可能有效:

struct data_t {
    Eigen::Matrix2f matrix;
    EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};