Метод виртуального дочернего класса Pybind11 не вызывается во время рекурсии, вместо него вызывается Base
У меня есть простой тестовый пример полиморфизма, который работает не совсем правильно. У меня есть два класса C++, Client и Dispatcher. Диспетчер имеет метод "Dispatch", который принимает Client* в качестве входных данных и вызывает клиентский виртуальный метод ProcessEvent(). Я сделал оба этих класса доступными для Python, используя код ниже. Я получил класс Client как класс Python SomeClient и переопределил его функцию ProcessEvent. Когда я вызываю "Dispatch" из любой точки, кроме EXCEPT внутри метода SomeClient:: ProcessEvent, все работает как положено, я получаю отчет от дочернего класса. Но когда я вызываю Dispatch из SomeClient:: ProcessEvent, вызывается базовый класс ProcessEvent. Есть идеи, что здесь может пойти не так? Я ожидаю получить бесконечную рекурсию, в результате которой SomeClient:: ProcessEvent будет вызываться вечно.
C++:
#include <iostream>
#include "pybind11/pybind11.h"
namespace py = pybind11;
class Dispatcher;
class Client
{
public:
Client(Dispatcher* disp): PtrD(disp)
{
std::cout << "In Client::Client\n";
}
virtual ~Client(){};
virtual void ProcessEvent()
{
std::cout << "THIS SHOULDN'T HAPPEN --In Client::ProcessEvent\n";
}
Dispatcher* PtrD;
};
class Dispatcher
{
public:
Dispatcher()
{
std::cout << "In Dispatcher::Dispatcher\n";
}
virtual ~Dispatcher(){};
void Dispatch(Client* client)
{
std::cout << "Dispatcher::Dispatch called by " << client << std::endl;
client->ProcessEvent();
}
};
class DispatcherTrampoline : public Dispatcher
{
public:
using Dispatcher::Dispatcher;
};
class ClientTrampoline : public Client
{
public:
using Client::Client;
void ProcessEvent() override
{
PYBIND11_OVERLOAD(void,Client,ProcessEvent,);
}
};
PYBIND11_MODULE(libTestCase,mod)
{
py::class_<Client,ClientTrampoline> cli(mod,"Client");
cli.def(py::init<Dispatcher* >());
cli.def("ProcessEvent",&Client::ProcessEvent);
cli.def_readwrite("PtrD",&Client::PtrD);
py::class_<Dispatcher,DispatcherTrampoline> dsp(mod,"Dispatcher");
dsp.def(py::init< >());
dsp.def("Dispatch",&Dispatcher::Dispatch);
}
Тест Python:
from build.libTestCase import Client,Dispatcher
class SomeClient(Client):
def __init__(self,d):
print("In SomeClient::__init__")
super().__init__(d);
def ProcessEvent(self):
print("in SomeClient::ProcessEvent,about to call self.ProcessEvent")
self.PtrD.Dispatch(self);
if __name__ == "__main__":
dd = Dispatcher()
cl = SomeClient(dd)
dd.Dispatch(cl)
ТЕРМИНАЛЬНЫЙ ВЫХОД:
In Dispatcher::Dispatcher
In SomeClient::__init__
In Client::Client
Dispatcher::Dispatch called by 0x20bb270
in SomeClient::ProcessEvent,about to call self.ProcessEvent
Dispatcher::Dispatch called by 0x20bb270
THIS SHOULDN'T HAPPEN --In Client::ProcessEvent