Jetzt stellte sich jedoch heraus, dass es nützlich sein würde, den Anfang zu haben Methode von Foo, um Schlüsselwortargumente zu übernehmen (
Code: Select all
pybind11::kwargs
In meinem Projekt habe ich auch eine Klasse Caller, die eine Sammlung von Foos enthält. Der Aufrufer stellt eine Methode start bereit, die die start-Methode des erforderlichen foo aufruft und die
weiterleitet
Code: Select all
kwargs
Der Aufruf der Startmethode von Caller aus Python generiert jedoch immer den folgenden Fehler :
Code: Select all
TypeError: start() takes 1 positional argument but 2 were given
Datei foo.h/cpp
Code: Select all
#pragma once
#include
#include
// c++ class
class Foo {
public:
Foo() = default;
virtual ~Foo() = default;
virtual void start(pybind11::kwargs args) {}
virtual void update(double) {}
};
// trampoline class
class PyFoo : public Foo {
public:
using Foo::Foo; // Inherit constructors
void PyFoo::start(pybind11::kwargs args) override {
std::cout start(std::move(args));
}
void add(pybind11::object foo) {
_objs.push_back(foo);
_controllers.push_back(foo.cast());
}
private:
std::vector _objs;
std::vector _controllers;
};
Code: Select all
namespace py = pybind11;
PYBIND11_MODULE(untitled3, m) {
py::class_(m, "Foo")
.def(py::init());
py::class_(m, "Caller")
.def(py::init())
.def("add", &Caller::add)
.def("start", &Caller::start);
}
Code: Select all
import untitled3
class Bar(untitled3.Foo):
def __init__(self):
super().__init__()
def start(self, **kwargs):
print('ici')
def update(self, dt):
print('here')
c = untitled3.Caller()
c.add(Bar())
c.add(Bar())
c.start(1)