• 我的第一份供lua调用的c模块


    #include <stdio.h>
    #include <string>
    
    #include <direct.h>
    #include <windows.h>
    #include <io.h>
    
    
    extern "C" {
    #include "D:myPathlua5.3includelua.h"
    #include "D:myPathlua5.3includelauxlib.h"
    #include "D:myPathlua5.3includelualib.h"
    }
    #pragma comment(lib,"D:\myPath\lua\5.3\lib\Lua53.lib")// 该模块和lua解释器都要使用动态链接
    // 因为这是lua解释器也要用到的库,使用静态链接会报错 multiple Lua VMs detected
    
    #define LUA_VERSION_NUM 503
    
    // 使用static 防止名字污染
    static int pusherror(lua_State *L, const char *info) // lua函数返回错误信息就是这么来的
    {
        lua_pushnil(L);  // lua函数不是一出错就先返回  nil + info 的模式么?
        if (info == NULL)
            lua_pushstring(L, strerror(errno));
        else
            lua_pushfstring(L, "%s: %s", info, strerror(errno));
        lua_pushinteger(L, errno);
        return 3;
    }
    // 获取当前目录  因为会用到系统有关的目录api,所以cl编译时 运行时库选择 /MD 
    static int get_dir (lua_State *L)
    {
    #ifdef NO_GETCWD
        lua_pushnil(L);
        lua_pushstring(L, "Function 'getcwd' not provided by system");
        return 2;
    #else
        char *path = NULL;
        /* Passing (NULL, 0) is not guaranteed to work. Use a temp buffer and size instead. */
        size_t size = MAX_PATH; /* initial buffer size */
        int result;
        while (1)
        {
            path = (char *)realloc(path, size);
            if (!path) /* failed to allocate */
                return pusherror(L, "get_dir realloc() failed");
            if (_getcwd(path, size) != NULL)
            {
                /* success, push the path to the Lua stack */
                lua_pushstring(L, path);
                result = 1;
                break;
            }
            if (errno != ERANGE) { /* unexpected error */ //就是说expected的error 是ERANGE,
                result = pusherror(L, "get_dir getcwd() failed");
                break;
            }
            /* ERANGE = insufficient buffer capacity, double size and retry */
            size *= 2; 
        }
        free(path);
        return result;
    #endif
    }
    
    
    static int l_split(lua_State*L){
     const char* s = luaL_checkstring(L,-2);
     const char* sep = luaL_checkstring(L,-1);
    lua_newtable(L);
    const char* e = s;
    int i = 1;
      while((e= strchr(s,*sep))!=NULL){
        if(e-s==0){s=e+1;continue;} // 避免连续的*sep导致压入空串
        lua_pushlstring(L, s, e-s);
        lua_rawseti(L, -2, i++);
        s = e+1;
      }
      lua_pushstring(L, s);
      lua_rawseti(L, -2, i);
    
    return 1;
    }
    static int gettable(lua_State *L)
    {
        //lua_setfield lua_seti lua_settable   luaL_ref
        //lua_getfield lua_geti  lua_gettable   luaL_unref
        // luaL_unref是删除键值对 luaL_ref是自动生成唯一键
        lua_newtable(L);
        char value[32] = {0};
        char key[10] = {0};
        for(int i = 1; i <= 5; i++)
        {
            sprintf(value, "value: %d", i);
            lua_pushstring(L, value);
            lua_seti(L, -2, i);
        }
    
        for(int i = 6; i <= 10; ++i)
        {
            sprintf(key, "key %d", i);
            sprintf(value, "value %d", i);
            lua_pushstring(L, value);
            lua_setfield(L, -2, key);
        }
    
        for(int i = 11; i <= 15; ++i)
        {
            sprintf(key, "key %d", i);
            sprintf(value, "value %d", i);
            lua_pushstring(L, key);
            lua_pushstring(L, value);
            lua_settable(L, -3);
        }
    
        for(int i = 16; i <= 20; ++i)
        {
            sprintf(value, "value %d", i);
            lua_pushstring(L, value);
            luaL_ref(L, -2); // 这个 不用管key, luaL_ref是自动生成唯一的key
        }
    
        return 1;
    }
    
    // assumes the table is on the top of stack
    static int printtable(lua_State *L)
    {
        if(!lua_istable(L, -1))return 0;
        lua_len(L, -1);
        int nlen = lua_tointeger(L, -1);
        lua_pop(L, 1);// 注意 这里不是索引而是数量
        printf("table length:%d
    ",nlen);
        for(int i = 1; i <= nlen; ++i)
        {
            lua_geti(L, -1, i);
            int t = lua_type(L, -1);
            switch(t)
            {
            case LUA_TSTRING:
                printf("%s
    ", lua_tostring(L, -1));
                break;
            case LUA_TNUMBER:
            {
                if(lua_isinteger(L, -1))printf("%d
    ", lua_tointeger(L, -1) );
                else printf("%f
    ", lua_tonumber(L, -1));
            }
            break;
            default:printf("other type
    ");
            }
            lua_pop(L, 1);
        }
        return 0;
    }
    static const struct luaL_Reg mylib[] =
    {
        {"currentdir", get_dir},
        {"l_split", split},
        {"gettable", gettable},
        {"printtable",printtable},
        {NULL, NULL},
    };
    
    extern "C" __declspec(dllexport) int luaopen_mylib(lua_State *L)  // 必须是luaopen_+dll名的形式
    //requre(name)=>会找name.dll 找到name.dll 中的 luaopen_name导出函数
    {
        //luaL_register(L,"mylib",mylib); // 已弃用 会污染全局namespace
    
        //前面还可以加一些元表信息
        //设置 __gc  __index等写法
        luaL_newlib(L, mylib);
        // lua_setglobal(L, "mylib"); // 有了这一句就可以不用mylib =  require("mylib")了
    
        
        lua_pushliteral(L, "Copyright (C) 2003-2016 Kepler Project");
        lua_setfield(L, -2, "_COPYRIGHT");
        lua_pushliteral(L, "1.0 ");
        lua_setfield(L, -2, "_VERSION");
        return 1;
    }
    
  • 相关阅读:
    操作系统——第四章 文件管理
    操作系统——第三章 内存管理
    操作系统——第二章 进程管理
    last-child到底怎么用
    Https个人总结
    白话https
    RSA算法
    算法导论笔记:11散列表(哈希表)
    算法导论笔记:10基本数据结构(番外)
    算法导论笔记:09中位数和顺序统计量
  • 原文地址:https://www.cnblogs.com/ShawSpring/p/6082950.html
Copyright © 2020-2023  润新知