luacurl源码阅读2 - binding函数(static函数)
注册在curl表下,可以看作curl类的static函数
static const struct luaL_reg luacurl_funcs[] = { {"new", lcurl_easy_init}, {"escape", lcurl_escape}, {"unescape", lcurl_unescape}, {0, 0} }; LUACURL_API int luaopen_luacurl (lua_State *L) { //...... luaL_openlib (L, LUACURL_LIBNAME, luacurl_funcs, 0); //新建一个表 curl, 压入栈顶, 将表保存在: 栈[LUA_GLOBALSINDEX]["curl"] = curl, 函数注册在curl下 //...... return 1; //栈顶弹出1个元素, 作为lua层拿到的返回值 }
lcurl_easy_init函数
/* Initializes CURL connection */ static int lcurl_easy_init(lua_State* L) { printf("lcurl_easy_init begin: %d, %s\n", lua_gettop(L), lua_typename(L, lua_type(L, -1)) ); // curlT* c = (curlT*)lua_newuserdata(L, sizeof(curlT)); //创建一个userdata, 并压入栈顶 printf("lcurl_easy_init 111: %d, %s\n", lua_gettop(L), lua_typename(L, lua_type(L, -1)) ); // c->L=L; //关联lua虚拟机指针 //设置初始值 c->freaderRef=c->fwriterRef=c->fprogressRef=c->fheaderRef=c->fioctlRef=LUA_REFNIL; c->rud.nval=c->wud.nval=c->pud.nval=c->hud.nval=c->iud.nval=0; c->rudtype=c->wudtype=c->pudtype=c->hudtype=c->iudtype=LUA_TNIL; /* open curl handle */ c->curl = curl_easy_init(); /* set metatable to curlT object */ luaL_getmetatable(L, CURLHANDLE); //获取栈[LUA_REGISTRYINDEX][CURLHANDLE]处的table, 并压入栈顶, 如果没有则压入nil printf("lcurl_easy_init 222: %d, %s\n", lua_gettop(L), lua_typename(L, lua_type(L, -1))); // lua_setmetatable(L, -2); //相当于setmetatable(userdata, curlT),执行完后栈顶弹出1个元素 printf("lcurl_easy_init end: %d, %s\n", lua_gettop(L), lua_typename(L, lua_type(L, -1))); // return 1; //栈顶弹出1个元素, 作为lua层拿到的返回值 }
上面的代码相当于lua代码:
local curlContext = {} setmetatable(curlContext, curlT) return curlContext;
下面的lua代码,就会调用c层的lcurl_easy_init
local curl = require("luacurl") local obj = curl.new()
lcurl_escape函数
/* Escapes URL strings */ static int lcurl_escape(lua_State* L) { printf("lcurl_escape begin: %d, %s\n", lua_gettop(L), lua_typename(L, lua_type(L, -1)) ); // 1, string if (!lua_isnil(L, 1)) //栈底的值的类型是否为nil, 用栈底是因为可以给escape传多个参数, 但只会取第1个参数 { const char* s=luaL_checkstring(L, 1); printf("lcurl_escape 111: %d, %s\n", lua_gettop(L), lua_typename(L, lua_type(L, -1)) ); // 1, string lua_pushstring(L, curl_escape(s, (int)lua_strlen(L, 1))); printf("lcurl_escape end: %d, %s\n", lua_gettop(L), lua_typename(L, lua_type(L, -1)) ); // 2, string return 1; //栈顶弹出1个元素, 作为lua层拿到的返回值 } else { luaL_argerror(L, 1, "string parameter expected"); } printf("lcurl_escape end: %d, %s\n", lua_gettop(L), lua_typename(L, lua_type(L, -1))); return 0; }
下面的lua代码,就会调用c层的lcurl_escape
local curl = require("libcurl") local str = curl.escape("a b", "cd e") --第2个参数会被忽略 print(str) --a%20b
local str = curl.escape(function() end) --luaL_checkstring检查不通过,会报异常
lcurl_unescape函数
/* Unescapes URL encoding in strings */ static int lcurl_unescape(lua_State* L) { printf("lcurl_unescape begin: %d, %s\n", lua_gettop(L), lua_typename(L, lua_type(L, -1))); // 1, string if (!lua_isnil(L, 1)) { const char* s=luaL_checkstring(L, 1); printf("lcurl_unescape 111: %d, %s\n", lua_gettop(L), lua_typename(L, lua_type(L, -1))); // 1, string lua_pushstring(L, curl_unescape(s, (int)lua_strlen(L, 1))); printf("lcurl_unescape end: %d, %s\n", lua_gettop(L), lua_typename(L, lua_type(L, -1))); // 2, string return 1; //栈顶弹出1个元素, 作为lua层拿到的返回值 } else { luaL_argerror(L, 1, "string parameter expected"); } return 0; }
下面的lua代码,就会调用c层的unescape
local str2 = curl.unescape("a%20b") print(str2) --a b

浙公网安备 33010602011771号