我们正在尝试将Python作为脚本语言嵌入到使用C ++构建的游戏引擎中。 问题的摘要如下:
在python中调用返回指针的C ++函数会导致一个空对象。我们想直接从该指针调用/修改函数/变量。
Gameobject是一个C ++类,在调用Python Start()
行为时将传递该类。但是,在此游戏对象上调用任何方法(返回指针)都会导致空引用。
我们如何将C ++函数绑定到python模块,以便它返回有效的指针(由C ++和python共享)?
在绑定时,我们尝试了各种退货政策类型,但似乎都无效。例如:return_value_policy::reference
,return_value_policy::reference_internal
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());