luacurl源码阅读5 - Write回调和参数
writerCallback回调函数
static size_t writerCallback(void *ptr, size_t size, size_t nmemb, void *stream) { curlT* c=(curlT*)stream; //stream参数是一个自定义数据, 通过setopt(CURLOPT_WRITEDATA)设置的 lua_rawgeti(c->L, LUA_REGISTRYINDEX, c->fwriterRef); //栈[LUA_REGISTRYINDEX][xxxRefId]处的元素压入栈顶 pushLuaValueT(c->L, c->wudtype, c->wud); //size:每数据块大小, nmemb:数据块个数 lua_pushlstring(c->L, ptr, size * nmemb); lua_call(c->L, 2, 1); return (size_t)lua_tonumber(c->L, -1); }
下面的lua代码,就会调用到c层的write回调函数
local curl = require("luacurl") local respData = {} local c = curl.new() c:setopt(curl.OPT_URL, "http://httpbin.org/get") c:setopt(curl.OPT_WRITEDATA, respData); c:setopt(curl.OPT_WRITEFUNCTION, function(tab, str) if tab then --就是curl.OPT_WRITEDATA设置的对象 table.insert(tab, str) end return #str end); local isOk, err = c:perform() print("result", isOk, err, table.concat(respData)) c:close()
luaValueT
/* wrap values of arbitrary type */ union luaValueT { struct curl_slist *slist; curl_read_callback rcb; //读回调函数指针 curl_write_callback wcb; //写回调函数指针 curl_progress_callback pcb; #if CURL_NEWER(7,12,3) curl_ioctl_callback icb; #endif long nval; char* sval; void* ptr; };
curlT
/* CURL object wrapper type */ typedef struct { CURL* curl; //curl对象 lua_State* L; //lua虚拟机实例 int fwriterRef; //存放Opt_WriteFunction的参数值 int wudtype; //存放Opt_WriteData的参数类型 union luaValueT wud; //存放Opt_WriteData的参数值 int freaderRef; int rudtype; union luaValueT rud; int fprogressRef; int pudtype; union luaValueT pud; int fheaderRef; int hudtype; union luaValueT hud; int fioctlRef; int iudtype; union luaValueT iud; } curlT;
pushLuaValueT函数
/* push correctly luaValue to Lua stack */ static void pushLuaValueT(lua_State* L, int t, union luaValueT v) { switch (t) { case LUA_TNIL: lua_pushnil(L); break; case LUA_TBOOLEAN: lua_pushboolean(L, v.nval); break; case LUA_TTABLE: case LUA_TFUNCTION: case LUA_TTHREAD: case LUA_TUSERDATA: lua_rawgeti(L, LUA_REGISTRYINDEX, v.nval); break; //获取栈[LUA_REGISTRYINDEX][nval]处的元素并压入栈顶 case LUA_TLIGHTUSERDATA: lua_pushlightuserdata(L, v.ptr); break; //栈顶压入指针变量存放的地址 case LUA_TNUMBER: lua_pushnumber(L, v.nval); break; case LUA_TSTRING: lua_pushstring(L, v.sval); break; default: luaL_error(L, "invalid type %s\n", lua_typename(L, t)); } }

浙公网安备 33010602011771号