我在网上找到了某些库,但由于我需要提供的整体功能很少,我想知道是否有一种简单的方法可以做到这一点.
谢谢.
复杂的库API通常可以使用 SWIG快速(几乎)完全包装.在这种情况下使用SWIG的一个优点是很容易构建基于SWIG的包装器,可以在 18 major languages中使用库,包括Lua,Perl,Python ,Ruby和Java等.如果Lua是您首选(也可能是唯一)的关注点,那么我建议学习使用luaL_register()
作为策略的核心来在C中构建Lua模块.以这种方式构建模块的一个优点是您可以保留所有功能在单个名称空间中没有任何开销.您将需要创建一个与Lua C函数调用约定匹配的包装函数(就像您使用lua_register()一样)并从堆栈中收集Lua参数,调用包装函数,并将任何返回值和输出参数推回到Lua堆栈.关于如何解决这个问题的一个很好的概述可以在Lua中编程一书中找到.第一版的在线副本在Chapter 26讨论了库的创建,但是是为Lua 5.0编写的.我强烈要求任何认真使用Lua的人拥有当前版本PiL的副本.
不幸的是,Lua 5.1与5.0的差异最大的一个领域是动态加载模块(包括C和Lua)和require.
这是一个在Lua 5.1中工作的C库的完整(如果很小)示例.我们首先在C文件中实现包装器:
#include <lua.h> #include <luaxlib.h> #include <math.h> #undef PI #define PI (3.14159265358979323846) static int l_sin (lua_State *L) { double r = luaL_checknumber(L,1); lua_pushnumber(L, sin(r)); return 1; } static int l_cos (lua_State *L) { double r = luaL_checknumber(L,1); lua_pushnumber(L, cos(r)); return 1; } static const struct luaL_reg smlib [] = { {"sin", l_sin}, {"cos", l_cos}, {NULL, NULL} /* sentinel */ }; int luaopen_sm (lua_State *L) { luaL_openlib(L, "sm", smlib, 0); lua_pushnumber(L,PI); lua_rawset(L,-2,"pi"); return 1; }
请特别注意,需要导出的唯一函数是luaopen_sm(),其名称必须与将与require一起使用的模块的名称以及DLL文件的名称相对应.将该文件编译为名为sm.dll的DLL(可能在类Unix系统上命名为libsm.so),然后可以在Lua脚本中加载和使用它,如下所示:
require "sm" print(sm.sin(sm.pi/3), sm.cos(sm.pi/3));
此示例虽然未经测试,但应编译并运行.有关从math.h包装大多数函数的完整示例,请参阅随Lua一起分发的source to the math
module.因为这些瘦包装器包含大量重复代码,所以像SWIG这样的工具通常只能在每个函数的声明的情况下创建它们.
C类的包装方法原则上类似.每个Lua可调用包装器函数都需要一个可以在C端映射到它的参数,它必须实现为模块静态函数或静态成员函数,它也可以定位目标对象实例以及转换其他论点. SWIG特别擅长构建这种包装,并在此过程中隐藏了许多血腥细节.