• 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++呼叫。

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

  • 相关阅读:
    最大子序列、最长递增子序列、最长公共子串、最长公共子序列、字符串编辑距离等问题
    暑假总结20160907
    数组指针和指针数组的区别
    Matlab GUI界面
    稀疏表示(sparse representation)和字典学习
    C++设计模式——策略模式
    volatile,可变参数,memset,内联函数,宽字符窄字符,国际化,条件编译,预处理命令,define中##和#的区别,文件缓冲,位域
    MultiByteToWideChar和WideCharToMultiByte用法详解
    MFC中Listbox控件的简单使用
    window.open("url?param="+paramvalue) 服务端 乱码问题解决
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/4852638.html
Copyright © 2020-2023  润新知