编译Lua以及编写动态扩展

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 项目排在最上面),如果要设置依赖性,在任意一个项目的属性中设置:

编译Lua以及编写动态扩展_第1张图片

图 3 ‑ 1 CB 中设置项目依赖性

“ lua51 ”项目属性中,目标文件名要注意改一下,把“ lib ”前缀去掉:

编译Lua以及编写动态扩展_第2张图片

图 3 ‑ 2 去掉 DLL 项目目标文件的前缀

“ lua ”和“ luac ”项目的编译选项种中要加入对 lib 库的链接:

编译Lua以及编写动态扩展_第3张图片

图 3 ‑ 3 加入 lua51 的链接库

这样就可以编译了,编译出来的 lua.exe 、 luac.exe 和 lua51.dll 相当小,因为都动态链接到了“ msvcrt.dll”上,而不是那些恶心的“ msvcrXX.dll ”。

编译Lua以及编写动态扩展_第4张图片

图 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 同样非常小!

编译Lua以及编写动态扩展_第5张图片

图 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

你可能感兴趣的:(gcc,lua,dll,Build,扩展,编译器)