c++ + swig + lua ,三位一体,组合式开发
最近在做一个项目,然后出现了一个需求,就是需要使用C++ 开发软件,然后内置集成一个lua引擎,
lua引擎调用C++ 的接口,通过脚本来实现一些内置的功能。
我之前的做法是自己做适配层,自己来处理接口相关的事情。
然后通过插件的方式导出接口,最后自己来处理接口,自己来调用。
但是有个问题就是,我每次都要自己重新处理接口,每当出现新的接口的时候,我还要自己添加。
太费事,太繁琐。
直到有一天,我接触到了一套网游的源码,
网游大部分内置脚本都是lua,但是由于开发语言是C++ ,就涉及到了lua 和C++ 交互的问题,
这套网游源码给出了一个解决方案,就是 swig(swigwin)。
好了,进入正题,
swigwin 是什么,swig 是什么。
简单地说,它是一个接口处理工具,能处理多个不同平台和不同语言的接口。
http://www.swig.org/download.html
具体可以看官网。
准备工作:
C++ : vs 任意版本的编译器,我这里使用的是vs2017
lua : 任意版本的lua 引擎,我这里选择的是最新版lua5.4
swig : 上面官网可以下载,我这里使用的是最新版 swigwin4.0.2
开始干活:
使用vs2017,编译lua 脚本引擎。
然后,将要提供给lua 用的函数找出来。
根据不同的模块,写入不同的swig配置文件,例如
1 /**/ 2 %module zoo 3 4 %{ 5 #include "luacpp.h" 6 %} 7 8 int ZooPrint(char *szPrint);
这里需要解释一下,
第二行的zoo,是当前模块所在的包名字,或者是生成lua接口之后的库名字,
第四行和第六行之间的内容,会直接保留到生成的文件中,
第八行,是需要处理的函数,这个函数会被处理成lua 的接口。
这个文件准备好之后,就可以使用命令来处理这个文件了,
swig -c++ -lua -Wall swi.i
命令如上,含义是,调用swig 来处理一个 C++ 接口,导出为 lua 接口,-Wall 不关心,最后一个参数是配置文件名字,
执行了这条命令之后,会立刻在当前目录下生成一个叫做
swi_wrap.cxx
的文件,这个文件是个C++ 的源文件,它就是生成的接口文件。
这个文件非常大,无法完整地扔出来
SWIGEXPORT int SWIG_init(lua_State* L) /* default Lua action */
主要函数就是这一个,这是当前文件的对外接口,
参数是一个lua 解释器对象,功能是给这个解释器对象增加当前接口内的函数,之后可以直接用,
这里需要注意 SWIG_init 是一个宏,
只需要在lua解释器代码中,解释器对象初始化的时候调用一下此接口,内部的函数就可以使用了,
大致就是如下:
这里的zoo ,其实就是模块名,
除了这个函数,在接口文件中还有一个重要的结构,用来记录注册的函数,统一注册
重要的东西就这些,通过以上,就将C++接口导出给lua 了,
然后项目编译,链接,就可以执行了。
执行之后是这样:
需要“包名.函数名”然后调用,
有个问题是,这里需要用一个变量来接返回值,否则它会自动把返回值也打印出来,
并且,返回值的类型实际上是int ,但是这里展示出来是个 float,因为lua 的number型都是浮点数。
好了,到这里,整套开发流程就都结束了。
这里记录一下,我怕未来某一天会忘了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
2017-07-20 这群,什么玩艺