Replies: 5 comments 2 replies
-
Use the |
Beta Was this translation helpful? Give feedback.
-
i think i'm going to create a wrapper class for this struct that just contains pointers so I can better reason about preventing memory leaks etc. |
Beta Was this translation helpful? Give feedback.
-
I created a wrapper class but I am still having trouble creating a mutable reference to a vector of structs. This is how I am testing mutability: def test_slavelist():
context = ecx_contextt(maxslave=2, maxgroup=2)
context.slavelist[0].state = 13
assert context.slavelist[0].state == 13 which fails with:
my wrapper: #include <nanobind/nanobind.h>
#include <nanobind/stl/bind_vector.h>
#include <ethercat.h>
namespace nb = nanobind;
using namespace nb::literals;
using IOMapVector = std::vector<uint8_t>;
using ECSlaveTVector = std::vector<ec_slavet>;
using ECGroupTVector = std::vector<ec_groupt>;
class ecx_contextt_wrapper {
public:
ecx_contextt context;
ecx_portt port;
ECSlaveTVector slavelist;
int slavecount;
uint16_t maxslave;
ECGroupTVector grouplist;
uint8_t maxgroup;
uint8_t esibuf [EC_MAXEEPBUF];
uint32_t esimap [EC_MAXEEPBITMAP];
ec_eringt elist;
ec_idxstackT idxstack;
boolean ecaterror;
int64_t DCtime;
ec_SMcommtypet SMcommtype;
ec_PDOassignt PDOassign;
ec_PDOdesct PDOdesc;
ec_eepromSMt eepSM;
ec_eepromFMMUt eepFMMU;
ecx_contextt_wrapper(uint16_t maxslave_, uint8_t maxgroup_){
if (maxslave_ == 0) {
throw std::invalid_argument("maxslave cannot be zero.");
}
if (maxgroup_ == 0) {
throw std::invalid_argument("maxgroup cannot be zero.");
}
slavelist.resize(maxslave_);
maxslave = maxslave_;
grouplist.resize(maxgroup_);
maxgroup = maxgroup_;
context.port = &port;
context.slavelist = slavelist.data();
context.slavecount = &slavecount;
context.maxslave = maxslave;
context.grouplist = grouplist.data();
context.maxgroup = maxgroup;
context.esibuf = &esibuf[0];
context.esimap = &esimap[0];
context.esislave = 0;
context.elist = &elist;
context.idxstack = &idxstack;
context.ecaterror = &ecaterror;
context.DCtime = &DCtime;
context.SMcommtype = &SMcommtype;
context.PDOassign = &PDOassign;
context.PDOdesc = &PDOdesc;
context.eepSM = &eepSM;
context.eepFMMU = &eepFMMU;
context.FOEhook = nullptr;
context.EOEhook = nullptr;
context.manualstatechange = 0;
context.userdata = nullptr;
}
};
and my binding: nb::class_<ec_slavet>(m, "ec_slavet")
.def_rw("state", &ec_slavet::state)
nb::bind_vector<ECSlaveTVector>(m, "ECSlaveTVector");
nb::class_<ecx_contextt_wrapper>(m, "ecx_contextt")
.def("__init__", [](ecx_contextt_wrapper *context_wrapper, uint16_t maxslave, uint8_t maxgroup) {
new (context_wrapper) ecx_contextt_wrapper(maxslave, maxgroup);
}, "maxslave"_a, "maxgroup"_a)
.def_rw("port", &ecx_contextt_wrapper::port)
.def_rw("slavelist", &ecx_contextt_wrapper::slavelist); |
Beta Was this translation helpful? Give feedback.
-
after defining an the second methon in this works, but the first does not: def test_slavelist():
context = ecx_contextt(maxslave=2, maxgroup=2)
context.slavelist[0].state = 13
assert context.slavelist[0].state == 13
def test_slavelist2():
context = ecx_contextt(maxslave=2, maxgroup=2)
new_slave = ec_slavet()
new_slave.state = 13
context.slavelist[0] = new_slave
assert context.slavelist[0].state == 13 |
Beta Was this translation helpful? Give feedback.
-
because the return value policy of |
Beta Was this translation helpful? Give feedback.
-
I'm trying to wrap an annoying c struct that just contains pointers to a bunch of stuff.
The problem is I need a mutable reference to a c style array:
context->slavelist = new ec_slavet[maxslave];
and I would like my python api to look like this:
but slave list is a c array and I have not yet figured out how to create a mutable reference to it.
Perhaps I need to change my
__init__
arguments to require the user to pass the slavelist to the context struct initializer?Beta Was this translation helpful? Give feedback.
All reactions