Here is what I have tried so far.
#include <pybind11/pybind11.h>
#include <pybind11/functional.h>
#include <pybind11/stl_bind.h>
#include <pybind11/embed.h>
#include <pybind11/pytypes.h>
#include <pybind11/numpy.h>
#include <array>
struct A{
int a;
float b[10];
};
struct B{
int c;
A d[5];
};
namespace py = pybind11;
PYBIND11_MODULE(TestWrapper, m) {
PYBIND11_DTYPE(A, a, b);
py::class_<A>(m, "A")
.def(py::init<>())
.def_readwrite("a", &A::a)
.def_property("b", [](A &p)->pybind11::array {
auto dtype = pybind11::dtype(pybind11::format_descriptor<float>::format());
return pybind11::array(dtype, { 10 }, { sizeof(float) }, p.b, nullptr);
}, [](A& p) {});
py::class_<B>(m, "B")
.def(py::init<>())
.def_readwrite("c", &B::c)
.def_property("d", [](B &p)->py:array {
auto dtype = pybind11::dtype(py::format_descriptor<A>::format(),1);
return pybind11::array(dtype, { 10 }, { sizeof(A) }, p.d, nullptr);
}, [](B& p) {});
#ifdef VERSION_INFOB
m.attr("__version__") = VERSION_INFO;
#else
m.attr("__version__") = "dev";
#endif
}
In the python Interface
import TestWrapper as tm
input = tm.A()
output = tm.B()
When I look at what is stored in output.d it says,
data type "^T{i:a:(10)f:b:}" not understood
I have also tried to make a this array using A in python like,
instancelist = [ tm.A() for i in range(29)]
output.d = instancelist
Bu this also resutled into some error. Any help to make the original code work or any sort of workaround will be appriciated.
With the valuable comment provided by @pptaszni. Here is what is my implemetation for the original problem.
#include <pybind11/pybind11.h>
#include <pybind11/functional.h>
#include <pybind11/stl_bind.h>
#include <pybind11/embed.h>
#include <pybind11/pytypes.h>
#include <pybind11/numpy.h>
#include <array>
#include <pybind11/stl.h>
#include <pybind11/complex.h>
#include <pybind11/functional.h>
#include <pybind11/chrono.h>
struct A{
int a;
float b[10];
};
struct B{
int c;
//std::array <A, 5> d;
A d[5];
};
//function to be implemented with the original structure
bool doSomething(B* object)
{
object->c = 2;
for (int i = 0; i < 5; i++)
for (int j = 0; j < 10; j++)
{
object->d[i].b[j] = 2;
}
return true;
}
//wrapper around the main function with the function wrapper
class MyclassB{
public:
int c;
std::array <A, 5> d;
void doSomethingWrapper()
{
B b;
doSomething(&b);
c = b.c;
for (int i = 0; i < 5; i++)
for (int j = 0; j < 10; j++)
{
d[i].b[j] = b.d[i].b[j];
}
}
};
namespace py = pybind11;
PYBIND11_MODULE(TestWrapper, m) {
PYBIND11_NUMPY_DTYPE(A, a, b);
py::class_<A>(m, "A")
.def(py::init<>())
.def_readwrite("a", &A::a)
.def_property("b", [](A &p)->pybind11::array {
auto dtype = pybind11::dtype(pybind11::format_descriptor<float>::format());
return pybind11::array(dtype, { 10 }, { sizeof(float) }, p.b, nullptr);
}, [](A& p) {});
py::class_<MyclassB>(m, "MyclassB")
.def(py::init<>())
.def_readwrite("c", &MyclassB::c)
.def_readwrite("d", &MyclassB::d)
.def("doSomethingWrapper", &MyclassB::doSomethingWrapper);
#ifdef VERSION_INFOB
m.attr("__version__") = VERSION_INFO;
#else
m.attr("__version__") = "dev";
#endif
}
On the python interface, code seems like the same
import TestWrapper as tm
input = tm.A()
output = tm.MyclassB()
output.doSomethingWrapper()