封装Lua的调用

来源:互联网 发布:2016网络投资平台 编辑:程序博客网 时间:2024/06/05 02:34
 

 

/********************************************************************
 file name : LuaAPI.h
 author  : Clark
 created : 1:8:2011
 purpose : 封装Lua的调用
*********************************************************************/

#pragma once
#include <tchar.h>


extern "C"
{  
#include <lua.h> 
#include <lauxlib.h>   
#include <lualib.h>   
}


class LuaAPI
{
public:
 LuaAPI();
 ~LuaAPI();
 void init(const char* file_name) throw(TCHAR*);
 bool operator()(const char* func, const char* sig, ...); //lua_fun("func","di|d",x,y,&z)

private:
 LuaAPI(LuaAPI& luaAPI){ NULL; }
 LuaAPI& operator=(LuaAPI& luaAPI){ return *this; }
 void uninit();
 lua_State *m_pL;
};

 

 

//-------------------------------------------------------------

 

#include "LuaAPI.h"

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

LuaAPI::LuaAPI():m_pL(NULL)
{
}

LuaAPI::~LuaAPI()
{
 uninit();
}

void LuaAPI::init(const char* file_name) throw(TCHAR*)
{
 uninit();
 m_pL = lua_open();
    luaL_openlibs(m_pL);
    if( luaL_loadfile(m_pL, file_name))
 {
  TCHAR tcsError[512];
  _tcscpy(tcsError, _T("Failed in LuaAPI::init! -> "));
  _tcsncat(tcsError, _T(file_name), 256);
  _tcscat(tcsError, _T("\n"));
  throw tcsError;
 }
    lua_resume(m_pL, 0);
}

void LuaAPI::uninit()
{
 if( NULL != m_pL)
 {
  lua_close(m_pL);
 }
}

bool LuaAPI::operator()(const char* func, const char* sig, ...)
{
 if( NULL == m_pL)
  return false;

 va_list vl;
 int narg, nres;
 va_start(vl, sig);
 lua_getglobal(m_pL,func);

 //压入参数
 for(narg = 0; *sig; narg++)
 {
  luaL_checkstack(m_pL, 1, "too many arguments");
  switch(*sig++)
  {
  case 'd': lua_pushnumber(m_pL, va_arg(vl, double)); break;
  case 'i': lua_pushinteger(m_pL, va_arg(vl, int)); break;
  case 's': lua_pushstring(m_pL, va_arg(vl, char*)); break;
  case '|': goto endargs;
  default: NULL;
  }
 }
endargs:

 nres = strlen(sig);
 if( 0 != lua_pcall(m_pL, narg, nres, 0))
 {
  //error(m_pL,"error calling '%s': %s", func, lua_tostring(m_pL,-1));
  return false;
 }

 //检索结果
 nres = -nres;
 while(*sig)
 {
  switch(*sig++)
  {
  case 'd':
   {
    if(!lua_isnumber(m_pL, nres))
     break;
    *va_arg(vl, double*) = lua_tonumber(m_pL,nres);
   }
   break;
  case 'i':
   {
    if(!lua_isnumber(m_pL, nres))
     break;
    *va_arg(vl, int*) = lua_tointeger(m_pL,nres);
   }
   break;
  case 's':
   {
    if(!lua_isstring(m_pL, nres))
     break;
    *va_arg(vl, const char**) = lua_tostring(m_pL,nres);
   }
   break;
  default: NULL;
  }
  nres++;
 }
 va_end(vl);
 return true;
}

//-------------------------------------------------------------

 

/********************************************************************
 file name : const2buffer.h
 author  :  Clark
 created :  1:8:2011
 purpose :
*********************************************************************/
#pragma once
#include <tchar.h>
#include <windows.h>

class const2buffer
{
public:
 static const2buffer make_c2b(const TCHAR* pConst) throw(const TCHAR*)
 {
  try{ return (const2buffer(pConst)); }
  catch(const TCHAR* pError){ throw pError; }
 }
 explicit const2buffer(const TCHAR* pConst) throw(const TCHAR*):m_pBuf(NULL)
 {
  if( NULL != pConst)
  {
   int iLen = _tcslen(pConst);
   try{ m_pBuf = new TCHAR[iLen+1]; }
   catch(std::bad_alloc)
   {
    m_pBuf = NULL;
    TCHAR _tcsError[256];
    _stprintf(_tcsError,_T("Failed in const2buffer -> const2buffer -> new TCHAR[%d]\n"),iLen);
    throw _tcsError;
   }   
   _tcscpy(m_pBuf,pConst);
   m_pBuf[iLen] = '\0';
  }
 }
 ~const2buffer()
 {
  if( NULL != m_pBuf)
  {
   delete[] m_pBuf;
   m_pBuf = NULL;
  }
 }
 operator TCHAR*()
 {
  return m_pBuf;
 }

private:
 const2buffer(const2buffer& other){ NULL; }
 const2buffer& operator=(const2buffer& other){ return *this; }
 TCHAR* m_pBuf;
};


class a2w
{
public:
 explicit a2w():buffer(0){}
 explicit a2w(const char* str) throw(const TCHAR*):buffer(0)
 {
  try { init(str); }
  catch(const TCHAR* pError){ throw pError; }
 }
 a2w(a2w& other) throw(const TCHAR*):buffer(0)
 {
  try { *this = other; }
  catch(const TCHAR* pError){ throw pError; }
 }
 void init(const char* str) throw(const TCHAR*)
 {
  if( NULL != buffer)
   delete[] buffer;
  if(NULL != str)
  {
   int nLen = ::MultiByteToWideChar(CP_ACP,0,str,-1,NULL,0);
   try{ buffer = new wchar_t[nLen+1];}
   catch(std::bad_alloc)
   {
    buffer = NULL;
    TCHAR _tcsError[256];
    _stprintf(_tcsError,_T("Failed in a2w -> init -> new wchar_t[%d]\n"),nLen+1);
    throw _tcsError;
   }
   memset(buffer,0,(nLen+1)*sizeof(wchar_t)); 
   ::MultiByteToWideChar(CP_ACP,0,str,-1,buffer,nLen);
   buffer[nLen] = 0;
  }
 }
 ~a2w()
 { 
  delete[] buffer; 
 }
 a2w& operator=(a2w& other) throw(const TCHAR*)
 {
  if( NULL != buffer)
   delete[] buffer;
  if(NULL != other.buffer)
  {
   int nLen = wcslen(other.buffer);
   try{ buffer = new wchar_t[nLen+1];}
   catch(std::bad_alloc)
   {
    buffer = NULL;
    TCHAR _tcsError[256];
    _stprintf(_tcsError,_T("Failed in a2w::init -> new wchar_t[%d]\n"),nLen+1);
    throw _tcsError;
   }
   memset(buffer,0,(nLen+1)*sizeof(wchar_t)); 
   wcscpy(buffer,other.buffer);
   buffer[nLen] = 0;
  }
  return *this;
 }
 operator const wchar_t*() { return buffer; }

private:
 wchar_t* buffer;
};

class w2a
{
public:
 explicit w2a():buffer(0){}
 explicit w2a(const wchar_t* str) throw(const TCHAR*):buffer(0)
 {
  try { init(str); }
  catch(const TCHAR* pError){ throw pError; }
 }
 w2a(w2a& other) throw(const TCHAR*):buffer(0)
 {
  try { *this = other; }
  catch(const TCHAR* pError){ throw pError; }
 }
 void init(const wchar_t* str) throw(const TCHAR*)
 {
  if( NULL != buffer)
   delete[] buffer;
  if(NULL != str)
  {
   int nLen = WideCharToMultiByte(CP_ACP, 0, str, -1, NULL, 0, NULL, NULL);
   try{ buffer = new char[nLen+1]; }
   catch(std::bad_alloc)
   {
    buffer = NULL;
    TCHAR _tcsError[256];
    _stprintf(_tcsError,_T("Failed in w2a::init -> new char[%d]\n"),nLen+1);
    throw _tcsError;
   }
   memset(buffer,0,(nLen+1)*sizeof(char)); 
   ::WideCharToMultiByte (CP_ACP, 0,str, -1,buffer , nLen, NULL,NULL);
   buffer[nLen] = 0;
  }
 }
 ~w2a() {  delete[] buffer;  }
 w2a& operator=(w2a& other) throw(const TCHAR*)
 {
  if( NULL != buffer)
   delete[] buffer;
  if(NULL != other.buffer)
  {
   int nLen = strlen(other.buffer);
   try{ buffer = new char[nLen+1];}
   catch(std::bad_alloc)
   {
    buffer = NULL;
    TCHAR _tcsError[256];
    _stprintf(_tcsError,_T("Failed in w2a::init -> new char[%d]\n"),nLen+1);
    throw _tcsError;
   }
   memset(buffer,0,(nLen+1)*sizeof(char)); 
   strcpy(buffer,other.buffer);
   buffer[nLen] = 0;
  }
  return *this;
 }
 operator const char*() { return buffer; }

private:
 char *buffer;
};

 

//-------------------------------------------

#include <iostream>
#include "..\\GameAPI\\LuaAPI.h"
#include "..\\GameAPI\\const2buffer.h"

void fun1(w2a a)
{
 printf("fun1 %s\n",a);
}

void fun(a2w w)
{
 wprintf(L"fun %s\n",w);
 w2a a1(w);
 fun1(a1);
}

void fun2(LuaAPI* pLuaAPI, char*& pRet)
{
 (*pLuaAPI)("funHellow", "|s",&pRet);
}

void main()
{
 printf("Hello World!\n");
 int iSum = 0;
 LuaAPI lua_test;
 try
 {
  lua_test.init("lua_test.lua");
 }
 catch(TCHAR* pError)
 {
  printf("%s\n", pError);
  return;
 }

 lua_test("funAdd", "ii|i", 7, 4, &iSum);
 printf("%d\n",iSum);

 char* pRet = NULL;
 fun2(&lua_test, pRet);
 _tprintf(_T("%s\n"),const2buffer::make_c2b(pRet));
}