/********************************************************************
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));
}