VC驿站

 找回密码
 加入驿站

QQ登录

只需一步,快速开始

搜索
查看: 2849|回复: 3

[交流] C++虚函数 执行Lua脚本。实现Lua脚本执行lua_dostring 字符串到宿主源码实例

[复制链接]
24_avatar_middle
在线会员 发表于 2016-6-28 00:51:14 | 显示全部楼层 |阅读模式

VC驿站第一贴,首先必须的有质量,必须的显的有高度!而且还得是干货!

想了想,发个关于C++虚函数的源码例子。源码是很久以前写的。执行Lua脚本到某游戏字符串接口!实现字符串调用游戏内部函数。

无喜勿喷~~~


  新建WIN32控制台程序。~~~好像是废话!

首先我们定义头文件。

#pragma once
#include <iostream>
#include <Windows.h>
#define RD_M_D(x)   *((DWORD *)(x))
#define RD_M_BYTE(x)   *((BYTE *)(x))
#define RD_M_CHAR(x)  (CHAR*)(x)
#define RD_M_WCHAR(x)  (WCHAR*)(x)
#define RD_M_F(x)   *((FLOAT *)(x))
/************************************************************************/
这里来定义宿主基质,以及数据类型。
/************************************************************************/
//#define Lua_Base  RD_M_D(RD_M_D(0x12DF3A0)) //lua_state*L
typedef int (*Glua_dostring)(int, const char *);
typedef void (*Glua_gettable)(int,int);
typedef int (*Gplua_call)(int,int,int,int);
typedef int (*Glua_pushstring)(int,const char *);
typedef int (*Glua_pushnumber)(int,double);
typedef double(*Glua_tonumber)(int,double);
typedef const char*(*Glua_tostring)(int,int);
typedef int(*Glua_isnumber)(int,int);
typedef int(*Glua_toboolen)(int,int);
typedef int(*Glua_settop)(int,int);
typedef int (*Glua_CFunction) (int);
typedef int(*Glua_pushcclosure)(int,int,int);
typedef void(*Glua_settable)(int,int);
typedef int(*Glua_loadfile)(int,const char*);
typedef void(*Glua_remove)(int,int);
typedef void (*Glua_pushvalue)(int,int);
std::string ReadStringFromFile(std::string buf);
class GLua
{
public:
GLua::GLua();
virtual GLua::~GLua();
int lua_dostring (const char *);
void SetLua(int);
bool lua_register(const char *,int);
void lua_getglobal(const char*);
void lua_gettable(int);
int lua_loadfile(const char*);
const char*lua_tostring(int);
int lua_isnumber(int);
void lua_pcall(int,int,int);
void lua_dofile(const char*);
double lua_tonumber(int);
void lua_pop(int);
void lua_pushstring(const char*);
void lua_pushnumber(double);
bool lua_toboolean(int);
void lua_remove(int);
void lua_pushvalue(int);
private:
int GetLua();
Glua_dostring GLua_Dostring;
Glua_gettable GLua_Gettable;
Gplua_call   GpLua_Call;
Glua_pushstring GLua_Pushstring;
Glua_tonumber GLua_Tonumber;
Glua_settop   GLua_Settop;
Glua_settable GLua_Settable;
Glua_pushcclosure GLua_Pushcclosure;
Glua_tostring GLua_Tostring;
Glua_isnumber GLua_Isnumber;
Glua_loadfile GLua_Loadfile;
Glua_toboolen GLua_Toboolen;
Glua_pushnumber GLua_Pushnumber;
Glua_remove  GLua_Remove;
Glua_pushvalue GLua_Pushvalue;
void  HookDobuffer();
private:
DWORD L;
};

接下来定义cpp源文件,

好像忘记一件很重要的事情,就是解决方案需要添加依赖LuaPlus 静态库。请自行百度查找编译!


#include "luahelp.h"
GLua::GLua()
{
L=0;
HookDobuffer();
GLua_Dostring = (Glua_dostring)GetProcAddress(GetModuleHandle(L"LuaPlus.dll"),"lua_dostring");
GLua_Gettable = (Glua_gettable)GetProcAddress(GetModuleHandle(L"LuaPlus.dll"),"lua_gettable");
GpLua_Call=(Gplua_call)GetProcAddress(GetModuleHandle(L"LuaPlus.dll"),"lua_pcall");
GLua_Pushstring=(Glua_pushstring)GetProcAddress(GetModuleHandle(L"LuaPlus.dll"),"lua_pushstring");
GLua_Tonumber=(Glua_tonumber)GetProcAddress(GetModuleHandle(L"LuaPlus.dll"),"lua_tonumber");
GLua_Tostring=(Glua_tostring)GetProcAddress(GetModuleHandle(L"LuaPlus.dll"),"lua_tostring");
GLua_Settop=(Glua_settop)GetProcAddress(GetModuleHandle(L"LuaPlus.dll"),"lua_settop");
GLua_Settable=(Glua_settable)GetProcAddress(GetModuleHandle(L"LuaPlus.dll"),"lua_settable");
GLua_Pushcclosure=(Glua_pushcclosure)GetProcAddress(GetModuleHandle(L"LuaPlus.dll"),"lua_pushcclosure");
GLua_Isnumber=(Glua_isnumber)GetProcAddress(GetModuleHandle(L"LuaPlus.dll"),"lua_isnumber");
GLua_Loadfile=(Glua_loadfile)GetProcAddress(GetModuleHandle(L"LuaPlus.dll"),"luaL_loadfile");
GLua_Toboolen=(Glua_toboolen)GetProcAddress(GetModuleHandle(L"LuaPlus.dll"),"lua_toboolean");
GLua_Pushnumber=(Glua_pushnumber)GetProcAddress(GetModuleHandle(L"LuaPlus.dll"),"lua_pushnumber");
GLua_Remove=(Glua_remove)GetProcAddress(GetModuleHandle(L"LuaPlus.dll"),"lua_remove");
GLua_Pushvalue=(Glua_pushvalue)GetProcAddress(GetModuleHandle(L"LuaPlus.dll"),"lua_pushvalue");
}
GLua::~GLua()
{
}
void GLua::lua_pushvalue(int n)
{
GLua_Pushvalue(GetLua(),n);
}
void GLua::lua_gettable(int n)
{
GLua_Gettable(GetLua(),n);
}
void GLua::lua_remove(int n)
{
GLua_Remove(GetLua(),n);
}
double GLua::lua_tonumber(int n)
{
return GLua_Tonumber(GetLua(),n);
}
std::string ReadStringFromFile(std::string buf)
{
DWORD RSize;
HANDLE hFile=CreateFileA(buf.c_str(),GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
DWORD filesize = GetFileSize(hFile,NULL)+1;
const CHAR *pBuffer = (const CHAR*) malloc(filesize);
ZeroMemory((void*)pBuffer,filesize);
ReadFile(hFile, (void*)pBuffer, filesize, &RSize, NULL);
CloseHandle(hFile);
buf=pBuffer;
free((void*)pBuffer);
return buf;
}
void GLua::lua_dofile(const char*f)
{
lua_dostring(ReadStringFromFile(f).c_str());
}
void GLua::lua_pushstring(const char*n)
{
GLua_Pushstring(GetLua(),n);
}
void GLua::lua_pushnumber(double i)
{
GLua_Pushnumber(GetLua(),i);
}
void GLua::lua_pop(int n)
{
GLua_Settop(GetLua(),-(n)-1);
}
int GLua::GetLua()
{
return L;
}
void GLua::SetLua(int l)
{do
{
__try{
L=RD_M_D(RD_M_D(l));
}__except(1){Sleep(200);OutputDebugStringA("W");}
} while (0==L);
}
int GLua::lua_isnumber(int n)
{
return GLua_Isnumber(GetLua(),n);
}
bool GLua::lua_register(const char *FuncName,int pFun)
{
int L=GetLua();
if (L!=0)
{
  __try{
   GLua_Pushstring(L,FuncName);
   GLua_Pushcclosure(L,pFun,0);
   GLua_Settable(L,-10001);
   return true;
  }__except(1){OutputDebugStringA("lua_Register");return false;}
}
return false;
}
void GLua::lua_getglobal(const char*name)
{
GLua_Pushstring(GetLua(),name);
GLua_Gettable(GetLua(),-10001);
}
bool GLua::lua_toboolean(int n)
{
int r=0;
if(0!=GetLua()){
  r= GLua_Toboolen(GetLua(),n);
if (r==0)
  return false;
else
  return true;
}
return false;
}
const char*GLua::lua_tostring(int n)
{
__try{
  return GLua_Tostring(GetLua(),n);}
__except(1){
  return "ERROR :lua_Tostring";
  OutputDebugStringA("ERROR :lua_Tostring");
}
}
int GLua::lua_dostring (const char *buf)
{
__try{
  if (GLua_Dostring == NULL)
  {
   return -1;
  }
  GLua_Dostring(GetLua(),buf);
  return 0;
}__except(1){OutputDebugStringA(buf);return -1;}
}
int GLua::lua_loadfile(const char*file)
{
if(GLua_Loadfile(GetLua(),file)|| GpLua_Call(GetLua(), 0, 0, 0))
{
  return 1;
}
return -1;
}
void GLua::lua_pcall(int c,int r,int n)
{
GpLua_Call(GetLua(),c,r,n);
}
void GLua:: HookDobuffer()
{
DWORD lua_dowbuffer=(DWORD)GetProcAddress(GetModuleHandle(L"LuaPlus.dll"),"lua_dowbuffer");//lua_dostring 内部就是调用的 lua_dowbuffer函数
if (lua_dowbuffer)
{
  DWORD dwOldProctect;
  VirtualProtect((PVOID)(lua_dowbuffer+0x48), 5,PAGE_EXECUTE_READWRITE,&dwOldProctect);
  *(BYTE*)(lua_dowbuffer+0x48)=0x90;
  *(DWORD*)(lua_dowbuffer+0x48+1)=0x90909090;//90==nopDWORD lua_dowbuffer=(DWORD)GetProcAddress(LuaPlus,"lua_dowbuffer");//lua_dostring 内部就是调用的 lua_dowbuffer函数
  if (lua_dowbuffer)
  {
   DWORD dwOldProctect;
   VirtualProtect((PVOID)(lua_dowbuffer+0x48), 5,PAGE_EXECUTE_READWRITE,&dwOldProctect);
   *(BYTE*)(lua_dowbuffer+0x48)=0x90;
   *(DWORD*)(lua_dowbuffer+0x48+1)=0x90909090;//90==nop     这里是游戏内存接口。你懂得~~~~
  }
}
}


最后来实现mian函数~~
编译通过。~~~


//#include "StdAfx.h"
#include "MyLua.h"
char buffer[250];
MyLua::MyLua(void)
{
GLua::GLua();
}

MyLua::~MyLua(void)
{
}
void MyLua::OpenNpc(const char*n)
{
sprintf_s(buffer,"SetAutoRunTargetNPCName(\"%s\")",n);
lua_dostring(buffer);
}
int MyLua::GetSceneID()
{
lua_getglobal("GetSceneID");
lua_pcall(0,1,0);
retint=atoi(lua_tostring(-1));
lua_pop(1);
return retint;
}
int MyLua::GetMissionInfo_ScriptID()
{
lua_getglobal("DataPool");
lua_pushstring("GetMissionInfo_ScriptID");
lua_gettable(-2);
lua_pushvalue(-2);
lua_pcall(1,1,0);
retint=atoi(lua_tostring(-1));
lua_pop(1);
return retint;
}
void MyLua::InitThread(PVOID p)
{
MyLua*l=(MyLua*)p;
l->SetLua(((MyLua*)p)->L);
}
void MyLua::Init(int L1){
L=L1;
_beginthread(InitThread,0,this);
}
bool  MyLua::IsWindowShow(const char*name)
{
bool iRet=false;
lua_getglobal("IsWindowShow");
lua_pushstring(name);
lua_pcall(1,1,0);
iRet=lua_toboolean(-1);
lua_pop(1);
return iRet;
}
void MyLua::Setmetatable(const char*t)
{
sprintf_s(buffer,"setmetatable(_G,{__index = %s})",t);
lua_dostring(buffer);
}
void MyLua::SendMessageEx(HWND hWnd,const char*n)
{
sprintf_s(buffer,"%s",n);
for(int i=0;i<strlen(buffer);i++)
  SendMessage(hWnd, WM_IME_CHAR,(WPARAM)buffer[i],1);
}
char* MyLua::GetData(const char*data)
{
lua_getglobal("Player");
lua_pushstring("GetData");
lua_gettable(-2);
lua_pushvalue(-2);
lua_pushstring(data);
lua_pcall(2,1,0);
strcpy(buffer,lua_tostring(-1));
lua_pop(1);
return buffer;
}
_POS MyLua::GetPos()
{
lua_getglobal("Player");
lua_pushstring("GetPos");
lua_gettable(-2);
lua_pushvalue(-2);
lua_pcall(1,2,0);
pos.x=atoi(lua_tostring(-2));
pos.y=atoi(lua_tostring(-1));
lua_pop(2);
return pos;
}
MyLua m_L;
void WINAPI SetL(int L)
{
m_L.Init(L);
}
bool WINAPI IsWindow(const char*name)
{
return m_L.IsWindowShow(name);
}
void WINAPI setmetatable(const char*t)
{
m_L.Setmetatable(t);
}
void WINAPI sendmessageEx(HWND h,const char*n)
{
m_L.SendMessageEx(h,n);
}
int WINAPI GetScriptID()
{
return m_L.GetMissionInfo_ScriptID();
}
void WINAPI  openNpc(const char*m)
{
m_L.OpenNpc(m);
}
char* WINAPI getData(const char*n)
{
return m_L.GetData(n);
}
_POS WINAPI getPos()
{
return m_L.GetPos();
}
int WINAPI getSceneID()
{
return m_L.GetSceneID();
}
bool WINAPI loadfile(const char*f)
{
return m_L.lua_loadfile(f);
}
int WINAPI dostring (const char *n)
{
return m_L.lua_dostring(n);
}
bool WINAPI Register(const char *n,int f)
{
return m_L.lua_register(n,f);
}
void WINAPI getglobal(const char*n)
{
m_L.lua_getglobal(n);
}
void WINAPI gettable(int n)
{
m_L.lua_gettable(n);
}
const char* WINAPI tostring(int n)
{
return m_L.lua_tostring(n);
}
int WINAPI isnumber(int n)
{
return m_L.lua_isnumber(n);
}
void WINAPI pcall(int pParan,int ret,int error)
{
m_L.lua_pcall(pParan,ret,error);
}
void WINAPI dofile(const char*f)
{
m_L.lua_dofile(f);
}
double WINAPI tonumber(int n)
{
return m_L.lua_tonumber(n);
}
void WINAPI pop(int n)
{
m_L.lua_pop(n);
}
void WINAPI pushstring(const char*n)
{
m_L.lua_pushstring( n);
}
void WINAPI pushnumber(double n)
{
m_L.lua_pushnumber(n);
}
bool WINAPI toboolean(int m)
{
return m_L.lua_toboolean(m);
}
void WINAPI remove(int n)
{
m_L.lua_remove(n);
}
void WINAPI pushvalue(int n)
{
m_L.lua_pushvalue(n);
}





上一篇:Visual C++ 6.0网络及Internet开发指南(学习笔记)
下一篇:看帖有染UDP通信C#篇~
83_avatar_middle
在线会员 发表于 2016-6-28 23:03:24 | 显示全部楼层
把源码传上来吧,当程序里面一下看的清楚点。。。。
26_avatar_middle
在线会员 发表于 2016-7-14 11:26:16 来自手机 | 显示全部楼层
我就笑笑不说话1468465817.23
23_avatar_middle
在线会员 发表于 2016-9-9 18:23:28 | 显示全部楼层
楼主好人啊C++虚函数 执行Lua脚本。实现Lua脚本执行lua_dostring 字符串到宿主源码实例
您需要登录后才可以回帖 登录 | 加入驿站 qq_login

本版积分规则

关闭

站长提醒上一条 /2 下一条

QQ|小黑屋|手机版|VC驿站 ( 辽ICP备09019393号tongdun|网站地图wx_jqr

GMT+8, 2019-5-23 12:16

Powered by Discuz! X3.4

© 2009-2019 cctry.com

快速回复 返回顶部 返回列表