Мы пытаемся встроить 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());