Как изменить / получить доступ к указателю C ++, используя Pybind11 в скрипте Python? - PullRequest
0 голосов
/ 08 апреля 2019

Мы пытаемся встроить Python как язык сценариев в наш игровой движок, созданный с использованием C ++.Краткое описание проблемы:

Вызов функции C ++, которая возвращает указатель, в python приводит к нулевому объекту.Мы хотим напрямую вызывать / изменять функции / переменные из этого указателя.

Gameobject - это класс C ++, который передается при вызове поведения Python Start().Однако вызов любого метода (который возвращает указатель) для этого игрового объекта приводит к нулевой ссылке.

Как связать функцию C ++ с модулем python так, чтобы он возвращал действительный указатель (который являетсяиспользуется C ++ и python)?

Мы пытались использовать различные типы политик возврата при связывании, но ни один из них не работает.Например: return_value_policy::reference, return_value_policy::reference_internal

Определение функции C ++
MusicComponent* GetMusicComponent() 
{
    assert(HasComponent<MusicComponent>() && "Does not have component.");
    auto ptr(componentArray[GetComponentTypeID<MusicComponent>()]);
    return dynamic_cast<MusicComponent*>(ptr);
}
Реализация привязки Python
//Unique pointer because the destructor and constructor are private 
py::class_<Gameobject , std::unique_ptr<Gameobject, py::nodelete>>gameobject (IridiumModule, "GameObject");


gameobject.def("GetMusicComponent", &Gameobject::GetMusicComponent, py::return_value_policy::automatic_reference);
Скрипт Python
class PyScriptComponent():
    def Start(gameObject):       
       comp = gameObject.GetMusicComponent()
       print(comp) #prints none
       comp.PlayMusic() #error: null reference
Предоставление MusicComponent
PYBIND11_MODULE(IridiumPython, IridiumModule) 
{
    py::class_<MusicComponent>musicComponent (IridiumModule, "MusicComponent" , baseComponent);
    baseComponent.def(py::init<Gameobject*>());
    musicComponent.def("PlayMusic", &MusicComponent::PlayMusic);
}

Вызов функции Python в движке
pyObject.attr("Start")(GetGameobject());
...