luacurl源码阅读1 - 入口函数

从入口函数开始

LUACURL_API int luaopen_luacurl (lua_State *L) 
{  
    printf("luaopen_luacurl begin: %d, %s\n", lua_gettop(L), lua_typename(L, lua_type(L, -1))); // 1, string

    curl_global_init(CURL_GLOBAL_ALL); /* In windows, this will init the winsock stuff */

    createmeta(L);
    luaL_openlib (L, 0, luacurl_meths, 0); //将函数注册到curlT表下
    printf("luaopen_luacurl 111: %d, %s\n", lua_gettop(L), lua_typename(L, lua_type(L, -1)) ); // 2, table

    luaL_openlib (L, LUACURL_LIBNAME, luacurl_funcs, 0); //新建一个表 curl, 压入栈顶, 将表保存在: 栈[LUA_GLOBALSINDEX]["curl"] = curl, 函数注册在curl下
    printf("luaopen_luacurl 222: %d, %s\n", lua_gettop(L), lua_typename(L, lua_type(L, -1)) ); // 3, table

    set_info(L);
    setcurlerrors(L);
    setcurloptions(L);
    setcurlvalues(L);
    setcurlinfo(L);

    printf("luaopen_luacurl end: %d, %s\n", lua_gettop(L), lua_typename(L, lua_type(L, -1)) ); //3, table

    return 1; //栈顶弹出1个元素, 作为lua层拿到的返回值
}

 

入口函数是什么时候被调用,就是lua层调用下面的代码时:

local curl = require("luacurl")

"luacurl"字符串会先压入栈顶,然后调用c层的luaopen_luacurl

 

createmeta函数

static void createmeta (lua_State *L) 
{
    printf("createmeta begin: %d, %s\n", lua_gettop(L), lua_typename(L, lua_type(L, -1))); // 1, string

    luaL_newmetatable(L, CURLHANDLE); //新建表curlT(后续作为元表)压入栈顶, 并将该表存入栈[LUA_REGISTRYINDEX][CURLHANDLE]处
    lua_pushliteral(L, "__index"); //字符串压入栈顶
    lua_pushvalue(L, -2);  //curlT再压入栈顶
    printf("createmeta 111: %d, %s\n", lua_gettop(L), lua_typename(L, lua_type(L, -1))); // 4, table

    lua_rawset(L, -3); // curlT["__index"] = curlT, 执行完后栈顶弹出2个元素

    printf("createmeta end: %d, %s\n", lua_gettop(L), lua_typename(L, lua_type(L, -1))); // 2, table
}

 

luaL_openlib (L, 0, luacurl_meths, 0);

将函数注册到curlT表下

相当于lua代码:

local curlT = {}
栈[LUA_REGISTRYINDEX][CURLHANDLE] = curlT
curlT.__index = curlT

function curlT:close() end

function curlT:setopt() end

function curlT:perform() end

function curlT:getinfo() end

 

set_info函数

static void set_info (lua_State *L)
{
    //当前栈顶元素为curl表, 相当于curl["_COPYRIGHT"] = "xxx"
    LUA_SET_TABLE(L, literal, "_COPYRIGHT", literal, "(C) 2003-2006 AVIQ Systems AG");
    LUA_SET_TABLE(L, literal, "_DESCRIPTION", literal, "LuaCurl binds the CURL easy interface to Lua");
    LUA_SET_TABLE(L, literal, "_NAME", literal, "luacurl");
    LUA_SET_TABLE(L, literal, "_VERSION", literal, "1.1.0");
    LUA_SET_TABLE(L, literal, "_CURLVERSION", string, curl_version());
    LUA_SET_TABLE(L, literal, "_SUPPORTED_CURLVERSION", literal, LIBCURL_VERSION);
}

 

setcurlerrors函数

// 把curl.h中的CURLcode枚举值映射到lua中
static void setcurlerrors(lua_State* L)
{
    //当前栈顶元素为curl表, 相当于curl["OK"] = CURLE_OK的枚举值
    LUA_SET_TABLE(L, literal, "OK", number, CURLE_OK);
    LUA_SET_TABLE(L, literal, "FAILED_INIT", number, CURLE_FAILED_INIT);
    LUA_SET_TABLE(L, literal, "UNSUPPORTED_PROTOCOL", number, CURLE_UNSUPPORTED_PROTOCOL);

    //...
}

 

setcurloptions函数

//把curl.h中的CURLoption枚举值映射到lua中
static void setcurloptions(lua_State* L)
{
#undef C_OPT_SPECIAL
#undef C_OPT
#undef C_OPT_SL

//当前栈顶元素为curl表,相当于curl["OPT_Xxx"] = CURLOPT_Xxx

//CURLOPT_Xxx为curl.h中的CURLoption枚举值
#define C_OPT(n, t) LUA_SET_TABLE(L, literal, "OPT_"#n, number, CURLOPT_##n);
#define C_OPT_SL(n) C_OPT(n, dummy)
#define C_OPT_SPECIAL(n) C_OPT(n, dummy)

ALL_CURL_OPT
}

ALL_CURL_OPT宏:

#define ALL_CURL_OPT \
    C_OPT_SPECIAL(WRITEDATA) \ //相当于 curl["OPT_WRITEDATA"] = CURLOPT_WRITEDATA

    C_OPT(URL, string) \ //相当于 curl["OPT_URL"] = CURLOPT_URL
    C_OPT(PORT, number) \ //相当于 curl["OPT_PORT"] = CURLOPT_PORT
    C_OPT(POST, boolean) \ //相当于 curl["OPT_POST"] = CURLOPT_POST

    C_OPT_SL(HTTPHEADER) \ //相当于 curl["OPT_HTTPHEADER"] = CURLOPT_HTTPHEADER
//......

c语言宏tips: #是连接为字符串常量,##是连接为新的标识符

 

setcurlvalues函数

//把curl.h中的curlioerr,curliocmd, curl_proxytype, curl_ftpauth等枚举值以及一些常量值映射到lua中
static void setcurlvalues(lua_State* L)

 

setcurlinfo函数

//把curl.h中的CURLINFO枚举值映射到lua中
static void setcurlinfo(lua_State* L)
{
    //当前栈顶元素为curl表,相当于curl["INFO_Xxx"] = CURLINFO_Xxx
    LUA_SET_TABLE(L, literal, "INFO_NONE", number, CURLINFO_NONE);
    //luacurl.INFO_EFFECTIVE_URL = CURLINFO_EFFECTIVE_URL
    LUA_SET_TABLE(L, literal, "INFO_EFFECTIVE_URL", number, CURLINFO_EFFECTIVE_URL);
    LUA_SET_TABLE(L, literal, "INFO_RESPONSE_CODE", number, CURLINFO_RESPONSE_CODE);
    LUA_SET_TABLE(L, literal, "INFO_TOTAL_TIME", number, CURLINFO_TOTAL_TIME);

    //......
}

 

posted @ 2025-07-05 08:22  yanghui01  阅读(18)  评论(0)    收藏  举报