一直使用cocos自带的LUA绑定C++流程,项目服务器需求脱离cocos使用lua require C++的dll,研究了下,C++代码实现如下:
#include <iostream>
using namespace std;
extern "C" {
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#include "tolua/tolua++.h"
}
class Fish{
public:
Fish() :_positionX(0), _positionY(0), _positionZ(0), _name("defaule"){ cout << "the name is " << _name.c_str() << endl; }
~Fish(){};
std::string getName(){ return _name; }
void setName(std::string name){ _name = name; }
private:
std::string _name;
float _positionX;
float _positionY;
float _positionZ;
};
template <class T>
void object_to_luaval(lua_State* L, const char* type, T* ret)
{
if (nullptr != ret)
{
tolua_pushusertype(L, (void*)ret, getLuaTypeName(ret, type));
}
else
{
lua_pushnil(L);
}
}
// __declspec(dllexport)
static int ding_sum2(lua_State *L){
double d1 = luaL_checknumber(L, 1);
double d2 = luaL_checknumber(L, 2);
lua_pushnumber(L, d1 + d2);
return 1;
}
static const struct luaL_Reg global_lib[] = {
{ "global_lib", ding_sum2 },
{ NULL, NULL }
};
int lua_Fish_constructor(lua_State* L)//__cdecl
{
Fish* cobj = nullptr;
cobj = new Fish();
tolua_pushusertype_and_addtoroot(L, cobj, "Fish");
return 1;
}
bool luaval_to_std_string(lua_State* L, int lo, std::string* outValue, const char* funcName)
{
if (NULL == L || NULL == outValue)
return false;
bool ok = true;
tolua_Error tolua_err;
if (!tolua_iscppstring(L, lo, 0, &tolua_err))
{
ok = false;
}
if (ok)
{
size_t size;
auto rawString = lua_tolstring(L, lo, &size);
*outValue = std::string(rawString, size);
}
return ok;
}
int lua_Fish_Set_Name(lua_State* L)//__cdecl
{
int argc = 0;
Fish* cobj = nullptr;
tolua_Error tolua_err;
bool ok = true;
if (!tolua_isusertype(L, 1, "Fish", 0, &tolua_err)) goto tolua_lerror;
cobj = (Fish*)tolua_tousertype(L, 1, 0);
if (!cobj)
{
tolua_error(L, "invalid 'cobj' in function 'lua_Fish_Set_Name'", nullptr);
return 0;
}
argc = lua_gettop(L) - 1;
if (argc == 1)
{
std::string arg0;
ok &= luaval_to_std_string(L, 2, &arg0, "Fish:setName");
if (!ok)
{
tolua_error(L, "invalid arguments in function 'lua_Fish_Set_Name'", nullptr);
return 0;
}
cobj->setName(arg0);
lua_settop(L, 1);
return 1;
}
tolua_lerror:
tolua_error(L, "#ferror in function 'lua_Fish_Set_Name'.", &tolua_err);
return 1;
}
int lua_Fish_Get_Name(lua_State* L)//__cdecl
{
int argc = 0;
Fish* cobj = nullptr;
bool ok = true;
tolua_Error tolua_err;
if (!tolua_isusertype(L, 1, "Fish", 0, &tolua_err)) goto tolua_lerror;
cobj = (Fish*)tolua_tousertype(L, 1, 0);
if (!cobj)
{
tolua_error(L, "invalid 'cobj' in function 'lua_cocos2dx_Node_getChildByName'", nullptr);
return 0;
}
argc = lua_gettop(L) - 1;
if (argc == 0)
{
std::string arg0;
std::string ret = cobj->getName();
lua_pushlstring(L, ret.c_str(), ret.length());
return 1;
}
luaL_error(L, "%s has wrong number of arguments: %d, was expecting %d \n", "cc.Node:getChildByName", argc, 1);
return 0;
tolua_lerror:
tolua_error(L, "#ferror in function 'lua_cocos2dx_Node_getChildByName'.", &tolua_err);
return 0;
}
extern "C" {
int __declspec(dllexport) luaopen_fish(lua_State *L){
//luaL_newlib(L, ding_lib); // 5.2
tolua_open(L);
#ifndef Mtolua_typeid
#define Mtolua_typeid(L,TI,T)
#endif
tolua_usertype(L, "Fish");
Mtolua_typeid(L, typeid(CCSprite), "Fish");
tolua_module(L, nullptr, 0);
tolua_beginmodule(L, nullptr);
//tolua_usertype(L, "Fish");
tolua_cclass(L, "Fish", "Fish", "", nullptr);
tolua_beginmodule(L, "Fish");
tolua_function(L, "new", lua_Fish_constructor);
tolua_function(L, "getName", lua_Fish_Get_Name);
tolua_function(L, "setName", lua_Fish_Set_Name);
tolua_endmodule(L);
tolua_endmodule(L);
luaL_register(L, "global_lib", global_lib); // lua 5.1
return 1;
}
}
其中lua库直接使用库文件,tolua代码(只有几个)加入到项目里,lua测试代码如下:
require "fish"
print(global_lib.global_lib(23,17))
local fish = Fish:new()
fish:setName("wangyufeng");
print(fish:getName())