资讯专栏INFORMATION COLUMN

lua源码在windows下的编译,以及添加新的cc++模块

Sanchi / 672人阅读

摘要:中定义了,最后不要链接动态库重命名编译成的在生成库时不需要这两文件含有函数,否则在链接生成最终的文件时会有函数重定义的错误。链接步中编译出的文件,和步中生成的导出库,生成必须有才能运行。

本文环境为windows10+visual studio 2013
lua在linux下编译、添加cc++模块还是比较直接方便的,资料也多,windows就那么直接了,经过一番折腾终于成功了

编译源码

首先去官网下载最新的源码,解压
打开vs的命令行工具,如图,若要64位编译打开x64工具

进入解压的源码目录

抛开本身链接的运行时库类型(MD、 MT),编译可分两种,链接静态库或动态库

编译链接静态lib,最终生成lua.exe(解释器)、luac.exe(编译器)、lua.lib(静态链接库)
静态链接的lua.exe不依赖dll,但是无法添加新的cc++模块,因为相关函数不能link多份,只想把lua作为程序嵌入脚本或者运行纯lua静态链接更便捷
cl /MD /O2 /c  *.c
ren lua.obj lua.o
ren luac.obj luac.o
lib /OUT:lua.lib *.obj
link /OUT:lua.exe lua.o lua.lib
link /OUT:luac.exe luac.o lua.lib

1、各个c文件编译成obj文件
2,3、 lua.obj、luac.obj含有main函数,生成lib或dll时要排除
4、合并obj生成lib库,包含所有obj的函数
5、lua.o中有main函数,链接lua.lib生成lua.exe
6、luac.o中有main函数,链接lua.lib生成luac.exe

编译链接动态dll,最终生成lua.exe(解释器)、luac.exe(编译器)、lua.dll(静态链接库)、lua.lib(导出库)
动态链接的lua.exe依赖dll,后续可添加新的dll模块
cl /MD /O2 /c /DLUA_BUILD_AS_DLL *.c
ren lua.obj lua.o
ren luac.obj luac.o
link /DLL /IMPLIB:lua.lib /OUT:lua.dll *.obj 
link /OUT:lua.exe lua.o lua.lib
link /OUT:luac.exe luac.o *.obj

1:在cl编译的时候加入了一个自定义的宏 /DLUA_BUILD_AS_DLL 这是因为在luaconf.h文件中定义了LUA_BUILD_AS_DLL宏:
#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    
它控制了__declspec(dllexport)和__declspec(dllimport)的定义,必须加上这个开关才有这两个定义,否则编译出来的DLL没有任何导出函数。luac.c中定义了LUA_CORE,最后不要链接动态库
2、3:重命名编译成的lua.obj luac.obj 在生成dll库时不需要这两文件(含有main函数),否则在链接生成最终的exe文件时会有函数重定义的错误。
4:链接1步中编译出的obj文件,生成lua.dll和导出库lua.lib,如果没有定义DLUA_BUILD_AS_DLL 宏,不会生成导出库lua.lib,无法进行最后的链接,lua.lib中只有声明导出的函数(LUA_API),所以链接生成luac.exe时要链接*.obj文件。
5:链接1步中编译出的lua.obj文件(lua.o),和4步中生成的导出库,生成lua.exe(必须有lua.dll才能运行)。
6:链接luac.o,不能链接llua.lib导出库(只有导出函数,有些函数找不到),重新链接所有的obj,运行不依赖lua.dll,因为*.obj是__declspec(dllexport)编译生成,链接还会生成luac.lib导出库,应该和lua.lib是一样的

也可以在vs建立相关项目,将全部源码文件添加,根据需要排除或添加lua.cluac.c,配置相关属性进行编译

编译脚本

两种编译方式写了bat脚本(同样要在vs的命令行工具中运行),放到解压目录,会将编译结果以及头文件拷贝到相应目录

build_dll.bat:

@echo off
rem out lua.exe luac.exe lua.lib lua.dll
set ver=5.3.0
set op=build_dll
md %op%
md %op%include
cd src
cl /MD /O2 /c /DLUA_BUILD_AS_DLL *.c
ren lua.obj lua.o
ren luac.obj luac.o
link /DLL /IMPLIB:lua.lib /OUT:lua.dll *.obj 
link /OUT:lua.exe lua.o lua.lib
link /OUT:luac.exe luac.o *.obj
move *.exe ..\%op%
move *.lib ..\%op%
move *.dll ..\%op%
del /q *.obj
del /q *.o
del /q *.exp
copy lua.h ..\%op%include
copy lualib.h ..\%op%include
copy lauxlib.h ..\%op%include
copy lua.hpp ..\%op%include
copy luaconf.h    ..\%op%include
cd ..

build_static.bat:

@echo off
set ver=5.3.0
set op=build_static
rem out lua.exe luac.exe lua.lib 
md %op%
md %op%include
cd src
cl /MD /O2 /c  *.c
ren lua.obj lua.o
ren luac.obj luac.o
lib /OUT:lua.lib *.obj
link /OUT:lua.exe lua.o lua.lib
link /OUT:luac.exe luac.o lua.lib
move *.exe ..\%op%
move *.lib ..\%op%
move *.dll ..\%op%
del /q *.obj
del /q *.o
del /q *.exp
copy lua.h ..\%op%include
copy lualib.h ..\%op%include
copy lauxlib.h ..\%op%include
copy lua.hpp ..\%op%include
copy luaconf.h    ..\%op%include
cd ..
编写cc++模块

1.在vs中建立c++项目dlltest,属性->常规->配置类型,选择动态库dll,
2.如果是拷贝所有lua源码去除lua.c、luac.c添加到项目,需要在属性->C/C++->预处理器中,添加宏定义LUA_BUILD_AS_DLL,
如果已有编译成的导入库lua.lib和lua.dll,不用定义LUA_BUILD_AS_DLL宏,导出库中本就是导出函数
拷贝头文件与lua.lib

配置属性->C/C++->常规->附加包含目录 和 配置属性->链接器->常规->附加库目录
或者直接在代码中写 #pragma comment(lib, "路径")
3.添加源文件dlltest.cpp

#include "../build_dll/include/lua.hpp"
#pragma comment(lib, "../build_dll/lua.lib")

#define EXTERN_C        extern "C"
#define API_DECLSPEC    __declspec(dllexport)


EXTERN_C static int l_mystr(lua_State *L)
{
    lua_pushstring(L, "looyer");//返回的第一个参数, 字符串“looyer” 
    lua_pushnumber(L, 37);//返回的第二个参数,数字37

    //返回第三个参数table = {["ac"] = 17, [2] = "bn"} 
    lua_newtable(L);//在栈顶创建一个table

    //方法一,设置table的键和值 
    lua_pushstring(L, "ac");
    lua_pushnumber(L, 17);
    lua_settable(L, -3);//在table中设置键值对["ac"] = 17, 设置后,自动pop掉栈顶的两个元素

    //方法二,设置table的键和值 
    lua_pushstring(L, "bn");
    lua_setfield(L, -2, "2");//将栈顶元素设置为键“2”的值,并且赋个索引为-2的栈中table

    return 3;//返回参数的个数 
}

//演示输入多个参数,检查输入一个数字,一个字符串,一个table 
EXTERN_C static int l_myadd(lua_State *L)
{
    int a = luaL_checknumber(L, 1);
    const char *p = luaL_checkstring(L, 2);
    lua_getfield(L, 3, "yt");//将第三个参数table的“yt”键的值压入栈 
    int b = luaL_checknumber(L, -1);//取出该“yt”键的值 
    lua_pushnumber(L, a + b);
    return 1;//返回一个参数 
}

//只有luaopen_dlltest需要dllexport
//_后要和生成的dll同名否则require找不到对应的库
EXTERN_C API_DECLSPEC int luaopen_dlltest(lua_State *L)
{
    luaL_Reg l[] = {
        { "mystr", l_mystr },
        { "myadd", l_myadd },
        { NULL, NULL },
    };
    luaL_newlib(L, l);
    return 1;
}

生成,在Release或Debug目录下拷贝dlltest.dll到运行目录

在运行目录编写mytest.lua

dlltest = require "dlltest"
local cpath = package.cpath..";"
print("-----------start-------------")
for path in string.gmatch(cpath, "(.-);") do
    print(path)
end
a, b, c = dlltest.mystr()
print(a,b,c)
print(c[ac], c[2])
print(c["ac"], c[2])
print(c["ac"], c["2"])
a = 10
b = "tty"
c = { ["yt"] = 19}
print(dlltest.myadd(a,b, c))
print("-----------end-------------")

在运行目录打开命令行,用lua.exe 运行mytest.lua

参考链接

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/61016.html

相关文章

  • Nginx编译安装

    摘要:编译安装编译工具依赖库库库库编译安装下载地址补充模块模块的安装下载地址附录说明定义一个目录,存放服务器上的文件,也就是的安装目录。启用或禁用构建一个模块来允许服务器使用方法。 Nginx编译安装 编译工具 ububtu: apt-get install build-essential apt-get install libtool centos: yum ...

    gotham 评论0 收藏0
  • 网狐荣耀6701/6801 手机打包发布

    摘要:环境环境主要用于资源打包发布安卓打包和模拟运行和调试。环境下,安卓打包修改文件,中的路径。目录下,提供了一键打包脚本发布版发布版会发布数到路径下。使用以下命令即可运行手机项目。 1.前言 本篇将介绍网狐cocos2dx-lua工程打包android的apk、ios编译过程以及vs2015模拟运行和调试、lua脚本热更新。关于网狐的服务端编译运行,请查看网狐6701/6801服务端编译 ...

    LancerComet 评论0 收藏0
  • 网狐荣耀6701/6801 手机打包发布

    摘要:环境环境主要用于资源打包发布安卓打包和模拟运行和调试。环境下,安卓打包修改文件,中的路径。目录下,提供了一键打包脚本发布版发布版会发布数到路径下。使用以下命令即可运行手机项目。 1.前言 本篇将介绍网狐cocos2dx-lua工程打包android的apk、ios编译过程以及vs2015模拟运行和调试、lua脚本热更新。关于网狐的服务端编译运行,请查看网狐6701/6801服务端编译 ...

    macg0406 评论0 收藏0
  • [转]:如何快速构建一个简单的程序

    摘要:例如顺便说一下,在下编译,是完全支持多任务的哦,默认就是自动多任务构建的,比起以前在里面用来编译快多了,因为下的就算你启用了也没啥效果,非常非常得慢。。。 首先我们通过内置的工程模板创建一个空工程: $ xmake create -P ./hello create hello ... create ok!? 这个时候xmake将会产生一些工程文件,如下: $ cd ./hello $...

    willin 评论0 收藏0
  • 开发者测试-采用精准测试工具对Spring Boot应用进行测试

    摘要:,整合刚才已经下载好了,现在我们添加文件标签加一行如下然后是和在文件中添加数据源配置连接本地,新建数据库,查询执行项目页面列出来的语句自动建立该项目需要的数据库内容。 简介:本文主要介绍把现今主流的springboot框架项目和精准测试工具进行结合和应用,通过精准测试的数据穿透、数据采集、测试用例与代码的双向追溯、数据分析等一系列精准测试的特有功能,达到对项目质量的保证。  本次环境搭...

    galois 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<