成品项目托管在gitee,地址:uniqptr/moe.flamehaze.CQLua
构建环境
- Visual Studio Community
- cmake
- vcpkg
第一次安装vcpkg的话记得执行这条命令vcpkg integrate install
,以便Visual Studio找到通过vcpkg安装的库。
依赖
- lua
- sol
vcpkg install sol2:x86-windows-static
项目设置
虽然依赖有CMake,但实际并不用它。酷Q本身只运行在Windows 32位环境,docker版也是用wine模拟出来的。所以直接拿Visual Studio建项目就好了。
项目建好之后微调下项目属性。
图2的目的是让编译完成的DLL直接复制到酷Q的开发目录里,便于加快调试。顺便说下这些POST_BUILD之类的玩意儿用CMake写真的头疼,从语法到文档都让人蛋疼无比,这玩意儿变成C/C++的跨平台构建最流行的工具着实太恶心人了。
CQP.DLL 相关略
略,这一块主要都是体力活,对相关API做点细微调整,整齐划一看着舒心。可以直接参考我的代码仓库。
Lua 绑定
直接用 Lua 的 C 接口虽然可以但没必要。这里使用 sol 来完成嵌入 Lua 解释器和绑定 API 的工作。
主要分两部分,一部分是绑定数据结构到usertype
,另一部分是导出API。
举个栗子来说,用户类型的绑定用了两个宏(大概也可以简化下,但想想还是没必要)。
#define LUA_USERTYPE(N, ...) l.new_usertype<N>(#N, __VA_ARGS__);
#define LUA_FIELD(T, N) #N, &T::N
LUA_USERTYPE(User,
LUA_FIELD(User, age),
LUA_FIELD(User, nickname),
LUA_FIELD(User, user_id),
LUA_FIELD(User, sex));
而绑定 API 就简单多了。
#define LUA_BIND(N) l.set_function(#N, cq::##N)
// Message
LUA_BIND(sendPrivateMsg);
LUA_BIND(sendGroupMsg);
LUA_BIND(sendDiscussMsg);
LUA_BIND(deleteMsg);
完整代码就看我仓库。
测试
主要是确定回调给的复杂数据结构能正确在C++端解码并传入Lua。
log.info('获取群信息')
for i, group in pairs(getGroupList()) do
local group_info = group.group_name .. ' (' .. group.group_id .. ')'
for _, member in pairs(getGroupMemberList(group.group_id)) do
group_info = group_info .. '\n' .. member.nickname .. ' (' .. member.user_id .. ')'
end
log.info(group_info)
end
log.info('获取好友列表')
for i, friend in pairs(getFriendList(0)) do
log.info(friend.nickname .. ' (' .. friend.user_id .. ')')
end
local stranger = getStrangerInfo(************, 0)
log.info('获取作者QQ信息: ' .. stranger.nickname .. ' (' .. stranger.user_id .. ')')
sendPrivateMsg(***********, '你好,我已在线')
效果截图如下
总结
没什么技术含量,不大擅长的活都让 sol 解决了。
我记得云风有几篇博客讲嵌入lua的坑的,这里找不到链接了。对lua感兴趣可以看看云风大大的博客,干货还是比较多的。不过嘛,有条件在实际工作中应用的人应该不多。。