原创作品,请注明出处转载CSDN:http://blog.csdn.net/relar/article/details/38084689

开发游戏server往往有“热更新”的需求,就是在不停止服务程序的情况下。对服务程序进行升级。

这里採用lua脚本桥接C++的模式。程序主框架用C++,程序的业务逻辑也是C++(详细的是C++写的DLL),这两者之间用LUA脚本语言进行桥接。当程序执行时,仅仅要改变LUA脚本,即能够选择使用不同的DLL。以实现业务逻辑的升级更新。

上演示代码,代码分为三部分,第一部分是主程序:

//本例演示了lua调用DLL

#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <conio.h>
#include "include\lua.hpp" int _tmain(int argc, _TCHAR* argv[])
{ int global_var1 = 0;
printf("这个程序演示Lua调用C++的Dll:\n");
lua_State *pLuaState = luaL_newstate(); //也能够用lua_open();
luaL_openlibs(pLuaState); if (luaL_dofile(pLuaState, "main2.lua"))// 载入脚本文件
{
printf("dofile error.\n");
}
_getch();
if (luaL_dofile(pLuaState, "main2.lua"))// 第二次载入脚本文件
{
printf("dofile error.\n");
}
_getch();
lua_close(pLuaState); return 0;
}

第二部分是DLL。我的project名称是Func1,编译出来的自然是Func1.dll

#include "my.h"

int GameLogic1(lua_State *L)
{
int n = lua_gettop(L);
double sum = 0;
int i; for (i = 1; i <= n; i++)
{ sum += lua_tonumber(L, i);
} lua_pushnumber(L, sum / n); lua_pushnumber(L, sum); return 2;
}
const struct luaL_Reg Func1lib[] = {
{ "GameLogic1", GameLogic1 },
{ NULL, NULL }
}; int luaopen_Func1lib(lua_State* L)
{
luaL_openlib(L, "Func1lib", Func1lib, 0);
return 1;
}

当中my.h的代码例如以下:

#include "include\lua.hpp"

#pragma comment(lib, "lua5.1.lib")

#if defined(_WIN32)
extern "C" _declspec(dllexport) int luaopen_Func1lib(lua_State* L); #else
extern "C" int luaopen_Func1lib(lua_State* L);
#endif

注意,上面extern "C"这几句曾让我浪费了不少时间。由于DLL是用C++写的。而LUA是用C写的。所以一定要用extern "C"语句。

以下是LUA脚本:

local testlib = package.loadlib("E://Func1.dll", "luaopen_Func1lib")
print(testlib)--, "Can not open testlib.")
if(testlib)then
testlib(); --调用DLL中抛出函数
a,b=Func1lib.GameLogic1(6,6)
print("average:",a,"sum:",b);
a,b=Func1lib.GameLogic2(3,6)
print("average:",a,"sum:",b);
else
print("Error")
end

这个脚本也让我浪费了非常长时间,它有两个陷阱,第一。它一定要写DLL的绝对路径,第二,这个脚本在LUA命令行中无法执行,仅仅有在C++程序中被调用。不注意这两点会让你疯掉。

另外我依照Func1.dll又写一个Func2.dll。内容稍有不同(这里就不必上代码了哈),演示的时候主程序执行了第一次载入脚本后会等待用户输入随意键。此时能够把脚本改为使用Func2.dll。再输入随意键让程序继续执行。业务逻辑就改了。

还有人是把业务逻辑以纯LUA实现,可是LUA自身功能有限。它天生就是用来打电话或C/C++呼叫。

版权声明:本文博主原创文章,博客,未经同意不得转载。

最新文章

  1. SpringMVC的小总结
  2. 使用SQL语句 检测 MSSQL死锁
  3. 【转】【C#】C#重绘windows窗体标题栏和边框
  4. redis 详解
  5. erl0009 - erlang 读取时间瓶颈解决办法
  6. Android 文件读写的例子
  7. GIS大讲堂内所有讲座的索引(更新至2008年6月26日)(转)
  8. 一些有用的 Emacs 配置(窗口快速切换、一键透明效果、任意位置删除整行等)
  9. 【6】Laravel5.1的migration数据库迁移
  10. UBUNTU13.04下Gedit打开txt文件乱码解决方法
  11. MFC知识点整理
  12. Memcached缓存系统介绍及安装
  13. 获取手机 id 与 ip
  14. iOS9新特性之常见关键字、泛型
  15. AsyncTask机制
  16. VMware虚拟机配置内网电脑能访问
  17. Excel动态图表
  18. C#基础知识总结(一)
  19. (02) 第一个springboot程序
  20. 在IDEA中停止和关闭SonarLint自动检查,手动运行SonarLint检查代码

热门文章

  1. 编译Nginx支持Tcp_warppers
  2. 即时编译和打包您的 Groovy 脚本(转)
  3. 【oracle案件】ORA-19502,ORA-27072
  4. ubuntu 12.04安装经典的Gnome桌面
  5. AC自己主动机 总结
  6. 重新想象 Windows 8 Store Apps (33) - 关联启动: 使用外部程序打开一个文件或uri, 关联指定的文件类型或协议
  7. yum使用总结(转)
  8. redmine忘记username和password
  9. Xcode_6.3_beta_4 官方 下载地址
  10. Oracle 初始化参数文件pfile和spfile