zoukankan      html  css  js  c++  java
  • lua转让C++书面DLL达到“热更新”

    原创作品,请注明出处转载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 "includelua.hpp"
    
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    
    	int global_var1 = 0;
    	printf("这个程序演示Lua调用C++的Dll:
    ");
    	lua_State *pLuaState = luaL_newstate(); //也能够用lua_open();
    	luaL_openlibs(pLuaState);
    
    	if (luaL_dofile(pLuaState, "main2.lua"))// 载入脚本文件
    	{
    		printf("dofile error.
    ");
    	}
    	_getch();
    	if (luaL_dofile(pLuaState, "main2.lua"))// 第二次载入脚本文件
    	{
    		printf("dofile error.
    ");
    	}
    	_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 "includelua.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++呼叫。

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

  • 相关阅读:
    WPF DelegateCommand 出现Specified cast is not valid
    WPF DelegateCommand 出现Specified cast is not valid
    WPF DelegateCommand 出现Specified cast is not valid
    win10 sdk 是否向下兼容
    win10 sdk 是否向下兼容
    win10 sdk 是否向下兼容
    PHP extract() 函数
    PHP end() 函数
    PHP each() 函数
    PHP current() 函数
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/4852638.html
Copyright © 2011-2022 走看看