Pybind11 Shared_ptr zu Python-implementierten Klassen nennt reine virtuelle anstelle von OverridePython

Python-Programme
Anonymous
 Pybind11 Shared_ptr zu Python-implementierten Klassen nennt reine virtuelle anstelle von Override

Post by Anonymous »

Ich habe ein Skriptfaktor -System, in dem ich ein Objekt habe, das Instanzen benutzerdefinierter Objekte erstellt, die in Python erstellt wurden, die aus einer abstrakten Basisklasse in C ++ abgeleitet sind. Die Objekte werden korrekt erstellt, aber wenn ich versuche, die Funktion "Override Python" zu verwenden, ruft sie die Basis c ++ reine virtuelle Funktion auf.

Code: Select all

#include
#include 
#include 
#include 
#include 

// Abstract class to be implemented in Python (the problematic one)
struct Script {
virtual ~Script() = default;
virtual void init() = 0;
};

// Class that generates scripts, (abstract, should be implemented in Python)
struct ScriptFactory {
virtual ~ScriptFactory() = default;
virtual std::shared_ptr getScript(const std::string& type) = 0;
};

// In this example, the class that generates the script using the ScriptFactory and attempts to use the generated script
class Container {
private:
std::shared_ptr script;
std::shared_ptr factory;
public:
Container(std::shared_ptr fact) : factory(fact) {};
void doSth(const std::string& name) {
script = factory->getScript(name);
script->init(); // Calls Script::init (pure virtual) instead of Pythons implementation
}
};

// ------------------- Wrappers -------------------

namespace py = pybind11;

struct PyScript : public Script {
using Script::Script;

void init() override {
PYBIND11_OVERRIDE_PURE(
void,
Script,
init
);
}
};

struct PyScriptFactory : ScriptFactory {
using ScriptFactory::ScriptFactory;

std::shared_ptr getScript(const std::string& type) override {
PYBIND11_OVERRIDE_PURE(
std::shared_ptr,
ScriptFactory,
getScript,
type
);
}
};

// ------------------- Bindings -------------------

PYBIND11_MODULE(MyTest, m) {
py::class_(m, "Script")
.def(py::init())
.def("init", &Script::init);

py::class_(m, "ScriptFactory")
.def(py::init())
.def("getScript", &ScriptFactory::getScript);

py::class_(m, "Container")
.def(py::init())
.def("doSth", &Container::doSth);
}
< /code>
Und hier der Python -Code, der ihn verwendet: < /p>
import MyTest as t

class MyFactory(t.ScriptFactory):
def __init__(self):
super().__init__()
self.scripts:dict = {}

def registerScript(self, script_name, func):
self.scripts[script_name] = func

def getScript(self, name):
return self.scripts[name]()

class MyScript(t.Script):
def __init__(self):
super().__init__()

def init(self):
print("Hello, world!")

# Creates the factory and registers the script
my_factory = MyFactory()
my_factory.registerScript("MyScript", lambda: MyScript())

# Creates the container and calls its function
my_cont = t.Container(my_factory)
my_cont.doSth("MyScript")

# Expected: 'Hello, world!'
# Real result: 'RuntimeError: Tried to call pure virtual function "Script::init"'
Aus allen Tests, die ich durchgeführt habe, sieht es so aus, als ob die C ++ - Seite den Link zur Überschreibung von Python verliert, aber ich bin mir nicht ganz sicher.

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post