Además de la respuesta de Tim, también puede optar por light userdata. No terminas con una copia de tus datos en la pila de Lua, todo lo que presionas para Lua es un puntero.
Lua no entiende qué hay en este puntero, si todavía apunta a la memoria válida, o cómo acceder a cualquier objeto en este puntero, por lo que tendrá que manejar todo esto usted mismo en C. Normalmente estoy enviar un puntero a un elemento en una lista, por lo que si hay algún riesgo de que la entrada se haya eliminado de la lista, primero repito la lista para validar el puntero (no es un gran problema si las listas son cortas). Para acceder a los elementos dentro del puntero en Lua, necesita escribir funciones get/set en C a las que puede llamar desde Lua.
Para empezar, aquí están las entradas de empuje y recuperar el lightuserdata:
Oh, wow. No sabía sobre esto. Este es definitivamente el camino a seguir si está usando luajit. –