Pasando ++ C objetos existentes a Lua y llamando a las funciones miembro objetos pasados

StackOverflow https://stackoverflow.com/questions/4523479

  •  12-10-2019
  •  | 
  •  

Pregunta

Estoy trabajando en un pequeño proyecto de simulación que utiliza Lua para conducir el comportamiento de las unidades individuales (hormigas) y usando Luabind para pegar el C ++ y los lados Lua juntos. Cada hormiga individuo (hay diferentes tipos, derivados de la Ant clase base) tiene una función Run (), que llama al script apropiado; la secuencia de comandos a continuación, lleva a cabo cualquier acción que deben tomarse, llamando a las funciones de la clase a la vista y posiblemente funciones gratuitas. He conseguido la función Ejecutar (en C ++) para ejecutar con éxito la función de ejecución coincidente en la secuencia de comandos Lua (que sólo imprime un texto en el momento).

void AntQueen::Run()
{
    lua->GetObject("QueenRun")(GetID());
}

lua es sólo una clase gerente que recupera la función de la secuencia de comandos. Lo anterior está llamando a la siguiente en un archivo de Lua:

function QueenRun(ID)
    print("The Queen is running!")
    print(ID)
end

Y Luabind miradas de registro de este tipo para la clase AntQueen:

void Register(lua_State *luaState)
{
    using namespace luabind;
    module(luaState)
    [
        class_<AntQueen, Ant>("AntQueen")
        .def("Eat", &AntQueen::Eat)
        .def("ExtractLarvae", &AntQueen::ExtractLarvae)
        .def("GetMaxLarvaeProduced", &AntQueen::GetMaxLarvaeProduced)
        .def("GetNumAvailLarvae", &AntQueen::GetNumAvailLarvae)
    ];
}

La forma en que está establecido ahora, se crean las hormigas, retirado, y se encontró a través de una simple fábrica / gerente. Cada hormiga puede ser recuperada llamando static Ant* AntFactory::GetAntByID(const int ID) que acaba encuentra la hormiga en un mapa hash y devuelve un puntero a la hormiga. Lo que estoy tratando de hacer es conseguir Lua a ser capaz de hacer algo como lo siguiente:

function QueenRun(ID)
    ant = GetAntByID(ID)
    larvae = ant:GetNumAvailLarvae()
    print(larvae)
    ant:Eat()
end

Lo anterior es sólo una compuesta por ejemplo, pero esperemos que muestra lo que estoy tratando de lograr. No quiero Lua a recoger la basura los objetos, porque ya se gestionan en el lado C ++. Mientras se probaba todo lo que fuera, cualquier intento de hacer lo siguiente:

ant = GetAntByID(ID)

en Lua resultó en abort() ser llamado y el programa de estrellarse y la quema.

R6010
-abort() has been called

Yo sólo parece estar perdiendo algo con lo que todo se iba y venía (esta es mi primera incursión en el encolado Lua y C ++ juntos allá de los programas de juguete). Estoy bastante seguro de pasar un puntero sin formato no es la manera de hacerlo; lightuserdata parece ser lo que estoy buscando, pero también tiene un montón de restricciones.

Para resumir: ¿Qué está pasando aquí que las causas abort ser llamado y cómo puedo utilizar Luabind / la API Lua C para obtener un puntero a un objeto de C ++ pasado a las funciones de Lua y miembros de llamada en ese puntero como si se tratara de un objeto (sin dejar que Lua recoger la basura)?

¿Fue útil?

Solución

La solución a este problema parecía estar atado a la clase AntFactory / funciones miembro de ser estático. Tan pronto como me cambié a registrar y utilizar esto:

//C++

static int AntFactory::CreateAnt(foo, bar)
{}

//Lua

factory:CreateAnt(foo, bar)

a un objeto instanciado y funciones miembro regulares como esto:

//C++

int AntFactory::CreateAnt(foo, bar)
{}

//Lua

factory:CreateAnt(foo, bar)

todo funcionó sin problemas en absoluto (después también empujando la fábrica a la tabla global). Creo que la razón de esto es que tratando de llamar a funciones miembro estáticas en un objeto no instanciado C ++ falla debido a Lua (o Luabind?) No ser capaz de tener un objeto de consulta para las llamadas.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top