Objeto de Python al puntero nativo de C ++

Estoy trabajando con la idea de usar python como un lenguaje de scripting incorporado para un proyecto en el que estoy trabajando y que la mayoría de las cosas funcionan. Sin embargo, parece que no puedo convertir un objeto extendido de Python de nuevo en un puntero nativo de c ++.

Así que esta es mi clase:

class CGEGameModeBase { public: virtual void FunctionCall()=0; virtual const char* StringReturn()=0; }; class CGEPYGameMode : public CGEGameModeBase, public boost::python::wrapper { public: virtual void FunctionCall() { if (override f = this->get_override("FunctionCall")) f(); } virtual const char* StringReturn() { if (override f = this->get_override("StringReturn")) return f(); return "FAILED TO CALL"; } }; 

Refuerzo de envoltura:

 BOOST_PYTHON_MODULE(GEGameMode) { class_("CGEGameModeBase", no_init); class_<CGEPYGameMode, bases >("CGEPYGameMode", no_init) .def("FunctionCall", &CGEPYGameMode::FunctionCall) .def("StringReturn", &CGEPYGameMode::StringReturn); } 

y el código de python:

 import GEGameMode def Ident(): return "Alpha" def NewGamePlay(): return "NewAlpha" def NewAlpha(): import GEGameMode import GEUtil class Alpha(GEGameMode.CGEPYGameMode): def __init__(self): print "Made new Alpha!" def FunctionCall(self): GEUtil.Msg("This is function test Alpha!") def StringReturn(self): return "This is return test Alpha!" return Alpha() 

Ahora puedo llamar al primero a las funciones bien haciendo esto:

 const char* ident = extract( GetLocalDict()["Ident"]() ); const char* newgameplay = extract( GetLocalDict()["NewGamePlay"]() ); printf("Loading Script: %s\n", ident); CGEPYGameMode* m_pGameMode = extract( GetLocalDict()[newgameplay]() ); 

Sin embargo, cuando bash convertir la clase Alpha a su clase base (última línea arriba), obtengo un error de impulso:

 TypeError: No registered converter was able to extract a C++ pointer to type class CGEPYGameMode from this Python object of type Alpha 

He hecho muchas búsquedas en la red pero no puedo resolver cómo convertir el objeto Alpha en su puntero de clase base. Podría dejarlo como un objeto, pero tenerlo como un puntero para que algún código que no sea de Python pueda usarlo. ¿Algunas ideas?

Gracias a Stefan de la lista de mailling de python c ++, faltaba

 super(Alpha, self).__init__() 

desde la llamada al constructor significa que nunca se hizo la clase padre. Pensé que esto habría sido automático: D

Solo otro problema que tuve fue guardar la nueva instancia de clase como una var global, de lo contrario se eliminó a medida que quedaba fuera del scope.

Tan feliz ahora

Bueno, no estoy seguro de si te ayudará, pero tuve el mismo problema con los scripts en Lua. Creamos objetos desde Lua y queríamos que algún código c ++ manejara los objetos a través de punteros. Hicimos lo siguiente:

  • todas las cosas de los objetos se escribieron en c ++, incluidos los constructores, los destructores y el método de fábrica;
  • lua code estaba llamando a un método de fábrica para crear un objeto. este método de fábrica 1) le dio al objeto un número de identificación único y 2) lo registró en el mapa c ++, que asignó los números de identificación a los punteros nativos;
  • por lo tanto, cuando lua iba a pasar un puntero al código c ++, en cambio daba un ID de objeto, y el código c ++ buscaba el mapa para encontrar el puntero real por ID.

Puede que no sea la respuesta que está buscando, pero eche un vistazo a ChaiScript para incrustarlo en su aplicación C ++.

Según su página web,

ChaiScript es el primer y único lenguaje de scripting diseñado desde cero con la compatibilidad con C ++ en mente. Es un lenguaje de tipo funcional integrado, inspirado en ECMAScript.

ChaiScript no tiene meta-comstackdor, ni dependencias de bibliotecas, ni requisitos de sistema de comstackción ni ningún tipo de equipaje heredado de ningún tipo. Puede trabajar sin problemas con cualquier función de C ++ que le exponga. No tiene que ser explicado explícitamente sobre ningún tipo, es función centrada.

Con ChaiScript, literalmente puede comenzar a crear secuencias de comandos de su aplicación agregando tres líneas de código a su progtwig y sin modificar los pasos de comstackción en absoluto.