LUA CPP "how to" 7/7
6) How to expose a Cpp Class to LUA using tolua++
At a glance:
A way to create instances of objects defined in Cpp from LUA scripts, so functions created in Cpp side should be called from LUA side. Somewhat the opposite direction of items 4, 5 and 6 of this series.
The way is not so difficult once you travelled it, as always!
First you have to write a header with your class declaration, then you have to use tolua++ application to translate it to LUA
I'll started a new cpp empty project, so i have only:
Main.cpp, App.h and App.cpp
Added:
cToLuaTest.h declaration of the class
cToLuaTest.cpp implementation of the class
cToLua translation to lua generated by tolua++
cToLua.cpp si generated by tolua++ with the following command line:
(on a terminal good great and legendary DOS window.. haa those times!)
tolua++ -o cToLua cToLuaTest.h
the command line explained:
a) first parameter -o nomGeneratedFile :desired name of outputfile
b) second parameter cToLuaTest.h :name of input file
this generates a long.. more than expected file, that at the end has a function:
https://dl.dropboxusercontent.com/u/78894295/leadwerks/cToLua.cpp
note: you will have to include as source this file, so name it differently than the
cToLuaTest.cpp which implements the class. If you do not especify -o, then the same name as input is assumend, becarefull
inside the cToLua.cpp generated by tolua++, almost at the end there is a special function:
/* Open function */ TOLUA_API int tolua_cToLua_open(lua_State* tolua_S) { ... }
which is used to bind the class to lua.
as a helper (from one of the threads cited on first tut) i adopted to write another header to declare the above function.
lua_gluecode.h
#pragma once #include "Leadwerks.h" using namespace Leadwerks; /* Exported function */ TOLUA_API int tolua_clasetolua_open(lua_State* tolua_S);
Following the class declaration and the implementation
class cToLuaTest { public: cToLuaTest(void){}; ~cToLuaTest(void){}; void luaCalling(void); float average(void); float aFloat; int intA, intB, intC; };
#include "cToLuaTest.h" //prototypes #include "Leadwerks.h" //uso System de leadwerks por eso la inclusion using namespace Leadwerks; void cToLuaTest::luaCalling(void){ System::Print("lua is calling me!"); } float cToLuaTest::average(void){ return (float)(intA+intB+intC)/3.0f; }
Did you expected something more elaborated? sorry then
Now the bind part, in Main.app:
1) include the file lua_gluecode.h
2) the following couple of sentences (before app->start)
#include "lua_gluecode.h" ... int main(int argc,const char *argv[]) { ... many many lines away of default main.cpp main function ... else { if (Interpreter::L == NULL) Interpreter::Reset(); //--- this line tolua_cToLua_open(Interpreter::L); // and this line //Execute mobile-style App script App* app = new App; if (app->Start()) { while (app->Loop()) {} ... rest of main.cpp }
build and voila!, you have all done cpp side!
now, go LUA side.
as a test, in App.lua, function Start:
function App:Start() ... --Load a map local mapfile = System:GetProperty("map","Maps/start.map") if Map:Load(mapfile)==false then return false end System:Print("app.lua start") -- cToLuaTest object created in lua c2luaTest = cToLuaTest:new() --create an instance of cToLuaTest class object if c2luaTest ~= nil then --test if ok System:Print("c2luaTest not nil") c2luaTest:luaCalling() --use one of it's methods, just print "lua is calling me!" on the cpp side end --set some properties c2luaTest.intA = 10 c2luaTest.intA = 35 c2luaTest.intA = 15 --call average an print out the result System:Print(c2luaTest:average()) return true end --of App:Start
so easy, isn't it?
the end
2 Comments
Recommended Comments