编译Lua以及编写动态扩展
2012-03-30 01:39
281 查看
1 前言
Lua 基本的编译说明在源代码包里的 INSTALL 文件中已经讲得很清楚,这里重点讲的是如何在 IDE 环境下面编译。2 Visual Studio 环境下的编译
创建一个解决方案“ lua ”,其中包含三个项目:两个控制台项目“ lua ”和“ luac ”,一个 dll 项目“ lua51”,按照 INSTALL 文件中的方法把源文件加到三个项目中,具体增加哪些文件其实很好记,“ lua51 ”项目去掉“ lua.c ”、“ luac.c ”和“ print.c ”,“ lua ”项目只需要“ lua.c ”,“ luac ”项目需要“ luac.c ”和“print.c ”。项目依赖性为:“ lua ”和“ luac ”都依赖于“ lua51 ”。
在三个项目选项中必须加入自定义编译选项“ /DLUA_BUILD_AS_DLL ”!否则编译出来的 DLL 没有任何导出函数(这是因为在“ luaconfig.h ”头文件中,“ LUA_BUILD_AS_DLL ”宏控制了“ __declspec(dllexport)”和“ __declspec(dllimport) ”的定义, VS 编译器在编译 DLL 时候需要这个定义,而 GCC 不需要)。
使用 VS 编译器,“ luac ”链接会不通过,提示找不到某些函数的定义,这其实是 BUG ,可以使用 SVN 下载最新的 lua 源代码解决,不过使用 GCC 是更好的方法。
3 Code::Blocks + GCC ( MinGW )环境下的编译
上面说到使用 GCC 是更好的方法,另一个原因是可以避免 Visual Studio 不同版本的 God Damned Fucking VC运行时问题(参见“ http://blog.koroirc.com/2008/06/visual-cpp-woes/ ”,静态连接可以解决这个问题,但是编译出来的文件要大一些,而且想想每一个编译出来的 exe 、 dll 中都塞着同样的代码,就很不爽!)。在 CB ( http://www.codeblocks.org/ )中创建解决方案和项目的方式差不多( CB 中),依赖性可以不用设置,直接调整项目的上下顺序即可( lua51 项目排在最上面),如果要设置依赖性,在任意一个项目的属性中设置:
图 3 ‑ 1 CB 中设置项目依赖性
“ lua51 ”项目属性中,目标文件名要注意改一下,把“ lib ”前缀去掉:
图 3 ‑ 2 去掉 DLL 项目目标文件的前缀
“ lua ”和“ luac ”项目的编译选项种中要加入对 lib 库的链接:
图 3 ‑ 3 加入 lua51 的链接库
这样就可以编译了,编译出来的 lua.exe 、 luac.exe 和 lua51.dll 相当小,因为都动态链接到了“ msvcrt.dll”上,而不是那些恶心的“ msvcrXX.dll ”。
图 3 ‑ 4 依赖性
4 编写简单的扩展
参考 http://blog.csdn.net/wzhwkent/archive/2009/07/20/4363367.aspx ,我这里把内容进行了化简。事实上就是编写一个 lua 能认的 dll ,在 GCC 环境下一切都是那么地简单:需要导出的函数或变量前面加上“extern ”关键字(不加也可以),不需要导出的,加上“ static ”关键字 - 标准 C 规范!
#include "../src/lua.h"
#include "../src/lualib.h"
#include "../src/lauxlib.h"
#include <math.h>
static int l_sin (lua_State *L) {
double d = luaL_checknumber(L, 1);
lua_pushnumber(L, sin(d));
return 1; /* number of results */
}
static struct luaL_reg lrLibs[] = {
{ "sin", l_sin
}, { NULL, NULL } /* sentinel */
};
extern int luaopen_mylib( lua_State* L ) {
luaL_register( L, "mylib", lrLibs );
return 1;
}
编译出来的 DLL 同样非常小!
图 4 ‑ 1 依赖性
图 4 ‑ 2 程序大小
写一个简单的 lua 脚本执行一下:
require("mylib");
print(mylib.sin(10));
执行结果:
D:/Lua/Release>lua test.lua
-0.54402111088937
Well done!
5 后记
还是 Linux 下面的那套规则爽,不过按照微软一贯的“简单问题复杂化”的思路,也正常,呵呵http://blog.csdn.net/shajunxing/article/details/5131069
相关文章推荐
- 编译Lua以及编写动态扩展
- 编译Lua以及编写动态扩展
- 通过编译luaSQL调用ODBC连接Access以及给OpenResty(LuaJIT)编写简单的C扩展示例
- 用apache的动态so模式编写和编译php扩展
- Lua5.3简单的C扩展示例以及与OpenResty(LuaJIT)的兼容编译
- 用apache的动态so模式编写和编译php扩展
- 用apache的动态so模式编写和编译php扩展
- apache静态编译和动态编译的理解以及用apache扩展模块的安装
- 【Programming In Lua (2E) 笔记】5:使用C++为Lua编写扩展库(macOS上两种动态库格式的坑)
- linux下驱动模块化编译,动态加载以及卸载
- Qt 4.7.4 完美动态编译发布动态调试,以及静态编译发布
- soap扩展编译,加载及动态加载
- VS2013编译生成Lua5.3.x动态链接库
- 安装php的mcrypt扩展(动态加载编译)
- [转]编译安装libevent,memcache,以及php的memcached扩展
- OpenRTMFP/Cumulus Primer(2)用Lua编写HelloWorld应用扩展CumulusServer
- Delphi编写DLL(以及静态和动态方式调用)
- LINUX下PHP编译添加相应的动态扩展模块so(不需要重新编译PHP,以openssl.so为例)
- 动态、静态编译以及MD、MDd、MT、MTd编译
- Linux下快速静态编译Qt以及Qt动态/静态版本共存