zoukankan      html  css  js  c++  java
  • Lua与C的交互

    • C与lua交互解释
    C和Lua的交互部分称为C API,C API是一个C代码和Lua代码进行交互的函数集,主要由以下部分组成:
    1、读取Lua全局变量的函数;
    2、调用Lua函数的函数;
    3、运行Lua代码片段的函数;
    4、注册C函数然后可以在Lua中被调用的函数;
    C语言和Lua之间的数据通信交换,是通过在C和Lua之间建立一个虚拟的栈,几乎所有的API调用都是对栈上的值进行操作,所有的数据交换也是通过这个栈来进行的,而这个栈是由Lua管理的,垃圾回收器知道哪个值正在被C使用。
    • C调用lua脚本
    lua脚本
    width = 100
    height = 101
    hello = 95050

    function add(a, b)
     return a + b + 100
    end
    main.c
    #include <stdio.h>
    #include "lua.h"
    #include "lauxlib.h"
    #include "lualib.h"

    int main(){
      lua_State *L = luaL_newstate();
     luaL_openlibs(L);

     if(luaL_loadfile(L, "test.lua") || lua_pcall(L, 0, 0, 0)){
     printf("error");
     return -1;
     }

     lua_getglobal(L, "width");
     lua_getglobal(L, "height");
     lua_getglobal(L, "hello");
     printf("width = %d
    ", lua_tointeger(L, -3));
     printf("height = %d
    ", lua_tointeger(L, -2));
     printf("%d
    ", lua_tointeger(L, -1));

     lua_getglobal(L, "add");
     lua_pushnumber(L, 100);
     lua_pushnumber(L, 180);
     //2代表参数个数,1代表返回结果个数
      int ret = lua_pcall(L, 2, 1, 0);
     if(ret){
     //代表调用出错
     }
     if(lua_isnumber(L, -1)){
     printf("%d", lua_tointeger(L, -1));
     }
     lua_close(L);
     return 0;
    }
    编译运行脚本
    gcc -lm -g -o test main.c ./liblua.a -ldl
    ./test
    • lua调用C的lib模块(需要lua 5.3以上的版本支持)
    mylib.c
    #include <stdio.h>
    #include "lua.h"
    #include "lauxlib.h"
    #include "lualib.h"
    #include <math.h>

    static int 
    myadd(lua_State *L){
      int a = luaL_checknumber(L, 1);
      int b = luaL_checknumber(L, 2);
     lua_pushnumber(L, a + b);
     return 1;
    }

    static const struct luaL_Reg mylib [] = {
     {"add", myadd},
     {NULL, NULL}
    };

    int luaopen_mylib(lua_State *L){
     luaL_newlib(L, mylib);
     return 1;
    }
    test.lua
    local lib = require "mylib"
    width = 100
    height = 101
    hello = 95050

    print(lib.add(1, 400))

    function add(a, b)
     return a + b + 100
    end
    编译脚本
    gcc mylib.c -fPIC -shared -o mylib.so
    eg:编译注解
    最主要的是GCC命令行的一个选项:
    -shared该选项指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连
    W类型的导出符号),不用该标志外部程序无法连接。相当于一个可执行文件

    -fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载
    入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。

    -L.:表示要连接的库在当前目录中

    -ltest:编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面
    加上.so来确定库的名称

    LD_LIBRARY_PATH:这个环境变量指示动态连接器可以装载动态库的路径。

    当然如果有root权限的话,可以修改/etc/ld.so.conf文件,然后调用 /sbin/ldconfig
    来达到同样的目的,不过如果没有root权限,那么只能采用输出LD_LIBRARY_PATH的方法
    了。
  • 相关阅读:
    docker启动mysql报错||docker ps没有容器,docker ps -a有发现断开了
    Mysql8.x配置安装(附高速下载)以及密码修改
    hibernate配置文件
    笔记,websocket不通,HikariPool Exception during pool initialization,文件下载跨域问题
    微服务中怎么将一个外部的jar添加到项目中
    postman测试需要校验权限的接口的方法
    通过Microsoft SQL Server Managerment Studio数据库管理工具创建SQL Server数据库的链接服务器
    Hashset和Treeset的区别
    maven项目抛出org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.IncompatibleClassChangeError: Implementing class
    MySQL索引
  • 原文地址:https://www.cnblogs.com/djzny/p/11050789.html
Copyright © 2011-2022 走看看