Кастинг 2D массива с помощью Pybind11 - PullRequest
1 голос
/ 02 июля 2019

Я создаю привязки Python для библиотеки C ++, для которой у меня есть файлы header / lib, но эта функция, которая принимает 2D-массив в качестве аргумента, не конвертируется автоматически Pybind11.Как правильно преобразовать этот аргумент?

Файл заголовка объявляет эту функцию как

class __declspec(dllimport) SomeClass {
    public:
        void function(uint32_t arg1, uint32_t arg2, float matrix[3][3]);

, и я связываю ее как

py::class_<SomeClass>(m, "_SomeClass", "SomeClass")
    .def("function", &SomeClass::function,
    py::arg("arg1"), py::arg("arg2"), py::arg("matrix"))

python setup.py bdist_wheel outputследующее (комментируя привязку function, строит колесо нормально)

C:\Users\joona\git\someproject\pybind11\include\pybind11\cast.h(1931,1): error C2664:  'Return pybind11::cpp_function::{ctor}::<lambda_b1f1895366c1273186f52810f5be9d13>::operator ()(Class *,uint32_t ,uint32_t ,float (*)[3]) const': cannot convert argument 4 from 'float *' to 'float (*)[3]' [C:\Users\joona\git\someproject\build\temp.win-amd64-3.7\Release\someproject.vcxproj]

1 Ответ

1 голос
/ 02 июля 2019

Я бы пошел с std::array:

class __declspec(dllimport) SomeClass {
    public:
        void function(uint32_t arg1, uint32_t arg2,
                      std::array<std::array<float,3>,3> matrix);
...
};

pybind будет знать, как преобразовать это в 2D-список. Кроме того, внутри вашего cpp-кода доступ такой же, как и для float[3][3].

EDIT:

Исходя из вашего комментария, я думаю, вы могли бы использовать что-то вроде этого (см. из документации Pybind ):

py::class_<SomeClass>(m, "SomeClass")
   .def("function", [](SomeClass& sc, uint32_t arg1, uint32_t arg2,
                       std::array<std::array<float,3>,3> m)
        {
            float M[3][3] = {{m[0][0], m[0][1], m[0][2]},
                             {m[1][0], m[1][1], m[1][2]},
                             {m[2][0], m[2][1], m[2][2]}};
            return sc.function(arg1, arg2, M);
        });

Здесь я предполагаю, что матрица является только входом для функции; Вы можете скопировать результат обратно в массив std, если он также выводится.

...