如何为lua写一个C library(如何在Lua中调用C代码/C动态库)?

  1. 下载lua源码,参考柴士童:在windows上编译linux源码在windows上用mingw编译安装到C:lua(例),并将源码src目录下的luaxx.dll复制到C:lualib目录下
  2. 这个链接下寻找legacy Windows package,解压后在根目录下运行以下命令将luarocks安装到C:luarocks:
.\install.bat /LUA "C:\lua" /INC "C:\lua\include" /LIB "C:\lua\lib" /BIN "C:\lua\bin" /MW /P "C:\luarocks"
  1. 新建目录mylib,在mylib目录运行命令luarocks write-rockspec,生成mylib-dev-1.rockspec文件,在mylib目录下新建目录src,在src目录下创建文件mylib.c,输入以下内容:
#include <math.h>
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"

//my C function to be registered to Lua
static int l_sin (lua_State *L) {
double d = lua_tonumber(L, 1); /* get argument */
lua_pushnumber(L, sin(d)); /* push result */
return 1; /* number of results */
}
static const struct luaL_Reg mylib[]={{"mysin", l_sin},{NULL,NULL}};
int luaopen_mylib(lua_State *L) {
    luaL_newlib(L, mylib);
    return 1;
}

回到上级目录,打开文件mylib-dev-1.rockspec,输入以下内容:

package = "mylib"
version = "dev-1"
source = {
   url = ""
}
description = {
   homepage = "*** please enter a project homepage ***",
   license = "*** please specify a license ***"
}
dependencies = {
   "lua >= 5.1, < 5.4"
   -- If you depend on other rocks, add them here
}
build = {
   type = "builtin",
   modules = {
    mylib = {"src/mylib.c"}
}
}

在mylib目录下运行命令luarocks make编译此C library,打开lua解释器输入m=require("mylib")导入自定义的C library

如果不想安装luarocks,也可以使用以下命令直接编译生成mylib.dll

gcc -O2 -c -o src/mylib.o -IC:\lua\include src/mylib.c
gcc -shared -o mylib.dll src/mylib.o C:\lua\lib/lua53.dll -lm 

随后在环境变量LUA_CPATH中添加.\?.dll即可使用require("mylib")在当前目录下使用编译好的C library了(注意:不要在LUA_PATH中添加.?.dll,否则?.dll文件会被当成lua脚本打开,从而报语法错误)

如何像python中的dir(a)函数一样打印变量a的所有方法?

for k in pairs(getmetatable(a).__index) do print(k) end

如何模仿C语言中的a?b:c表达式?

a and b or c

如何设定对象a的方法为b?

setmetatable(a,{__index=b})

如何设置x的缺省值为v?

x = x or v

如何将x近似成精度为两位小数的数?

x = x - x%0.01

如何将x近似到最近的整数?

x = math.floor(x + 0.5)

如何将x转为浮点数?

x = x + 0.0

如何将x强转为整数?

x = x | 0

如何将字符串s转成保存每个字符数值的数组?

array = {string.byte(s, 1, -1)}

如何按字符位置(如第5个字符)索引字符串的字符数值?

value = utf8.codepoint(s, utf8.offset(s, 5)) 

如何像python一样在数组a后append?

a[#a + 1] = v 
table.insert(a, v)

如何将数组a从i到j的元素整体平移至i+d到j+d?

table.move(a, i, j, i+d)

如何将函数nonils的参数打包成一个数组arg?

function nonils (...)
 local arg = table.pack(...)
 for i = 1, arg.n do
 if arg[i] == nil then return false end
 end
 return true
end

如何将数组a解包并用作函数f的输入参数?

f(table.unpack(a))

如何匹配空格分隔的字符串子串?

string.match(s, "(%S+)%s+(%S+)")

如何像python的inputstr.split(sep)一样将字符串s分割?

function mysplit (inputstr, sep)
        if sep == nil then
                sep = "%s"
        end
        local t={}
        for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
                table.insert(t, str)
        end
        return t
end

如何实现链表?

list = {next = list, value = v} -- 头插

如何实现集合set?

set[element] = true

如何实现包bag?

bag[element] = (bag[element] or 0) + 1

如何像python的s="\n".join(t)一样连接子串列表t构成字符串s?

t[#t + 1] = ""
s = table.concat(t, "\n")

如何只使用C动态库而不是同名lua脚本?

package.path = "" -- 清空lua脚本的搜索路径
local amoeba = require "amoeba"

标签: none

评论已关闭