LUA_API和LUALIB_API宏
目录

在Lua解释器源码中常常看到函数定义前有LUA_API宏和LUALIB_API宏,如:

LUA_API int lua_checkstack (lua_State *L, int size) {
......
}

LUALIB_API int luaopen_math (lua_State *L) {
......
}

这两个宏在“luaconf.h"中定义如下:

/*
@@ LUA_API is a mark for all core API functions.
@@ LUALIB_API is a mark for all standard library functions.
** CHANGE them if you need to define those functions in some special way.
** For instance, if you want to create one Windows DLL with the core and
** the libraries, you may want to use the following definition (define
** LUA_BUILD_AS_DLL to get it).
*/
#if defined(LUA_BUILD_AS_DLL)

#if defined(LUA_CORE) || defined(LUA_LIB)
#define LUA_API __declspec(dllexport)
#else
#define LUA_API __declspec(dllimport)
#endif

#else

#define LUA_API         extern

#endif

/* more often than not the libs go together with the core */
#define LUALIB_API      LUA_API

作用很明显了:

  • Lua编译时默认情况下是把core API函数和标准库函数编译到解释器中生成一个可执行文件,这时LUA_API就被替换成externextern关键字对于定义函数来说本来就是默认的属性,只不过隐式省略掉了。
  • 早期Lua用的最多的还是当做嵌入式语言使用,这时Lua的源码被编译成动态链接库。当声明了LUA_BUILD_AS_DLL时,core API函数和标准库函数被编译成动态链接库dll。进一步,如果定义了LUA_CORELUA_LIB,则LUA_API被替换成__declspec(dllexport),说明目标函数动态链接库中的通过动态符号表导出符号定义,即可以被调用这个动态链接库的程序可见。如果没有定义LUA_CORELUA_LIB,则LUA_API被替换成__declspec(dllimport),用来导入符号定义,看起来多次一举用,但是编译成汇编时引用函数会有少许优化,或正确处理函数中的静态变量。

参考

发表评论