基于上一篇文章
上一篇主要是因为不能调用lua函数 才那样解决,但是本篇能调用lua函数,那么目的实现也就简单多了
归其原因还是tolua 工具生成的hpp cpp文件的函数不对 虽然在c++中函数参数声明为LUA_FUNCTION 但是还是被当做了int处理
所以我们要手动处理函数的调用 也就是修改生成的 函数
...
生成的对应 代码 改为以下
if (NULL == tolua_S)
return 0;
int argc = 0;
NetMgr* self = nullptr;
#if COCOS2D_DEBUG >= 1
tolua_Error tolua_err;
if (!tolua_isusertype(tolua_S, 1, "cc.Http", 0, &tolua_err)) goto tolua_lerror;
#endif
self = static_cast<NetMgr*>(tolua_tousertype(tolua_S, 1, 0));
#if COCOS2D_DEBUG >= 1
if (nullptr == self) {
tolua_error(tolua_S, "invalid 'self' in function 'tolua_cocos2d_Node_registerScriptHandler'\n", NULL);
return 0;
}
#endif
argc = lua_gettop(tolua_S) - 1;
if (argc == 1)
{
#if COCOS2D_DEBUG >= 1
if (!toluafix_isfunction(tolua_S, 2, "LUA_FUNCTION", 0, &tolua_err))
goto tolua_lerror;
#endif
LUA_FUNCTION handler = toluafix_ref_function(tolua_S, 2, 0);
self->setLuaFunc(handler);
lua_settop(tolua_S, 1);
return 0;
}
luaL_error(tolua_S, "%s has wrong number of arguments: %d, was expecting %d\n", "cc.Node:registerScriptHandler", argc, 1);
return 0;
#if COCOS2D_DEBUG >= 1
tolua_lerror:
tolua_error(tolua_S, "#ferror in function 'tolua_cocos2d_Node_registerScriptHandler'.", &tolua_err);
return 0;
#endif
头文件改为
class toLuaFunc/*base class for to call lun function*/
{
public:
void setLuaFunc(LUA_FUNCTION handler);
protected:
void callLuaFunc(const char*ARG);
LUA_FUNCTION handler;
};
#define URL_BASE "http://127.0.0.1:8080/cocos/"
#define DATA_MAX_LENGTH 100
class NetMgr :public toLuaFunc
{
public:
static NetMgr*getInstance();
/**
* @brief new a HttpRequest
* @param action such as "login?name=1&&pass=1"
* @
*/
void getRequest(const char* action);
private:
NetMgr(){}
char _data[DATA_MAX_LENGTH];
};
cpp文件改为
#include "network_srv.h"
#include "CCLuaEngine.h"
#include "base/CCScriptSupport.h"
void toLuaFunc::setLuaFunc(LUA_FUNCTION handler)
{
this->handler = handler;
}
void toLuaFunc::callLuaFunc(const char*ARG)
{
CC_ASSERT(handler > 0, "call lua func 's handle must bigger than 0");
cocos2d::CommonScriptData data(handler, ARG);
cocos2d::ScriptEvent scriptEvent(cocos2d::kCommonEvent, &data);
cocos2d::LuaEngine::getInstance()->sendEvent(&scriptEvent);
}
void NetMgr::getRequest(const char* action)
{
log("c++ getRequest arg is %s",action);
string url = URL_BASE;
url += action;
HttpRequest*request = new HttpRequest;
request->setUrl(url.c_str());
request->setRequestType(HttpRequest::Type::GET);
request->setResponseCallback([=](HttpClient*client, HttpResponse *respone)
{
if (respone->getResponseCode() != 200)return;
vector<char>* buffer = respone->getResponseData();
CC_ASSERT(DATA_MAX_LENGTH > buffer->size(), " NetMgr buffer size overfloaw");
for (int i = 0; i < buffer->size(); i++)
{
_data[i] = (*buffer)[i];
}
_data[buffer->size()] = '\0';
callLuaFunc(_data);
});
HttpClient::getInstance()->setTimeoutForConnect(10);
HttpClient::getInstance()->send(request);
request->release();
}
NetMgr* NetMgr::getInstance()
{
static NetMgr* _netmgr__ = 0;
if (_netmgr__ == 0)
{
_netmgr__ = new NetMgr;
}
return _netmgr__;
}
lua文件
local function menuCallbackClose()
http:getRequest("login?name=1&&pass=1")
return
end
label=cc.LabelTTF:create("login","",35)
label:setPosition(self.size.width/2,self.size.height/2);
rootNode:addChild(label)
local menuToolsItem = rootNode:getChildByName("Button_1")
menuToolsItem:addTouchEventListener(menuCallbackClose)
local function callback(msg)
label:setString(msg);
end
http=NetMgr:getInstance();
http:setLuaFunc(callback);
其中cpp文件的还可以改为这样
void toLuaFunc::callLuaFunc(const char*ARG)
{
CC_ASSERT(handler > 0, "call lua func 's handle must bigger than 0");
/*
cocos2d::CommonScriptData data(handler, ARG);
cocos2d::ScriptEvent scriptEvent(cocos2d::kCommonEvent, &data);
cocos2d::LuaEngine::getInstance()->sendEvent(&scriptEvent);
*/
cocos2d::LuaEngine::getInstance()->getLuaStack()->pushString(ARG);
cocos2d::LuaEngine::getInstance()->getLuaStack()->executeFunctionByHandler(handler, 1);
cocos2d::LuaEngine::getInstance()->getLuaStack()->clean();
}
来源:oschina
链接:https://my.oschina.net/u/1391394/blog/521496