MFC lua编程之lua函数作为MFC内部函数调用

来源:互联网 发布:sql查看源代码 编辑:程序博客网 时间:2024/06/17 11:48

参考lua源码5.1.4版本源码

min.c文件:

/** min.c -- a minimal Lua interpreter* loads stdin only with minimal error handling.* no interaction, and no standard library, only a "print" function.*/#include <stdio.h>#include "lua.h"#include "lauxlib.h"static int print(lua_State *L){ int n=lua_gettop(L); int i; for (i=1; i<=n; i++) {  if (i>1) printf("\t");  if (lua_isstring(L,i))   printf("%s",lua_tostring(L,i));  else if (lua_isnil(L,i))   printf("%s","nil");  else if (lua_isboolean(L,i))   printf("%s",lua_toboolean(L,i) ? "true" : "false");  else   printf("%s:%p",luaL_typename(L,i),lua_topointer(L,i)); } printf("\n"); return 0;}int main(void){ lua_State *L=lua_open(); lua_register(L,"print",print); if (luaL_dofile(L,NULL)!=0) fprintf(stderr,"%s\n",lua_tostring(L,-1)); lua_close(L); return 0;}

由这个我呢间可知,可以使用lua_register()函数来使得lua可以使用C++定义的内部函数。

函数格式必须为static int , 其中int是指返回值个数。

lua脚本:

openHandle()wr(0x0000, 1, "data.dat", 0)wr(0x1000, 1, "data.dat", 512)wr(0x0010, 1, "$mem", 0)             -- 将内存中的数据写入磁盘wr(0x2000, 1, "data.dat", 1024)rd(0x0000, 1, "rdata.dat",0)rd(0x1000, 1, "rdata.dat",512)rd(0x2000, 1, "$mem",512)            -- 将从磁盘读出的数据写入内存rdmem(512,512,"rdata.dat",1536)    -- 将内存中的数据写入文件,参数含义为:内存偏移,数据大小(字节),文件路径,文件偏移slp(1000)randomseed(3)                      -- 初始化随机数种子x=random()                         -- 生成一个0-1之间的随机数y=random(10,100)                   -- 生成一个10-100之间的随机数z=random(10)                       -- 生成一个1-10之间的随机数printf('123,x=%0.3f, y=%d, z=%d,%s,%c\n',x,y,z,'Hello word','A') -- 打印函数wr(0x3000, 1, "data.dat", 1536)rd(0x3000, 1, "rdata.dat", 1024)cmp("$mem",512,"$mem",1024,1)        -- 比较 512,1024为偏移,1为sector.$mem 的位置可以是内存或文件closeHandle()

MFC对应的函数:

// print函数实现int CRunLuaDlg::luaPrintf(lua_State *L){int n = lua_gettop(L);if(!lua_isstring(L,1)){// 如果第一个参数不是string类型,则报参数错误g_lpWnd->AddLog(_T("printf arguarement invalid!\n"));return 0;}const char* fmt = lua_tostring(L,1);CArgList argList;for(int i=2;i<=n;i++){int nType = lua_type(L,i);switch (nType){case LUA_TNUMBER:  // double{double x = lua_tonumber(L,i);argList.AddArgu(x);}break;case LUA_TSTRING:  // string{const char *str = lua_tostring(L,i);argList.AddArgu(str);}break;case LUA_TBOOLEAN: // boolean{BOOL bVal = lua_toboolean(L,i);argList.AddArgu((BOOL)bVal);}break;}}char strfmt[512] = { 0 };g_lpWnd->FmtDecode(fmt,&argList,strfmt);TRACE(strfmt);g_lpWnd->AddPrint(strfmt);char lpstrlog[530] = { 0 };sprintf_s(lpstrlog,530,"add print:\"%s\"\n",strfmt);g_lpWnd->AddLog(lpstrlog);return 0;}// 设置随机数种子int CRunLuaDlg::luaRandomSeed(lua_State *L){int n = lua_tointeger(L,1);srand(n);CString strMsg;strMsg.Format(_T("srand(%d)\n"),n);g_lpWnd->AddLog(strMsg);return 0;}// 返回随机数int CRunLuaDlg::luaRandom(lua_State* L){CString strMsg;int argn = lua_gettop(L);if(argn == 0) // 返回0到1之间的随机数{double dx = (rand()%10000)*1.0/10000;lua_pushnumber(L,dx);strMsg.Format(_T("gen random num:%f\n"),dx);g_lpWnd->AddLog(strMsg);}else if(argn == 1) // 返回1 - n之间的整数{int n = lua_tointeger(L,1);int nx = 1+rand()%n;lua_pushinteger(L,nx);strMsg.Format(_T("gen random num:%d\n"),nx);g_lpWnd->AddLog(strMsg);}else // 返回n-m之间的随机整数{int n = lua_tointeger(L,1);int m = lua_tointeger(L,2);int nx = n + rand()%(m-n);lua_pushinteger(L,nx);strMsg.Format(_T("gen random num:%d\n"),nx);g_lpWnd->AddLog(strMsg);}return 1;}// 写数据到磁盘int CRunLuaDlg::luaWrite(lua_State *L){DWORD dwAddr         = lua_tointeger(L,1);DWORD dwSecNum       = lua_tointeger(L,2);   // Sectconst char *lpchFile = lua_tostring(L,3);DWORD dwOffset       = lua_tointeger(L,4);   // ByteCString strMsg;BOOL bRet = TRUE;DWORD dwBytes = dwSecNum * 512;LPBYTE lpBuff = new BYTE[dwBytes];ZeroMemory(lpBuff, dwBytes);if(strcmp(lpchFile,"$mem") == 0)      // 从内存读数据{strMsg.Format(_T("write mem data to disk (mem offset=%d, sect num=%d, addr=0x%X):"),dwOffset,dwSecNum,dwAddr);TRACE(strMsg);g_lpWnd->AddLog(strMsg);// 判断是否越界if(g_lpWnd->m_lpMemBuff == NULL || (g_lpWnd->m_dwMemSize-dwOffset) < (dwSecNum*512)){strMsg = _T(" Memmory out of boudary!");g_lpWnd->AddLog(strMsg);TRACE(strMsg);bRet = FALSE;}else{memcpy(lpBuff,g_lpWnd->m_lpMemBuff+dwOffset,dwSecNum*512); // 将内存中的数据拷贝到buff中}}else                                 // 从文件读数据{ LPWSTR lpwstrPath = AnsicToUnicode(lpchFile);strMsg.Format(_T("write file data to disk (file name=%s, data offset=%d, sect num=%d, addr=0x%X):"),lpwstrPath,dwOffset,dwSecNum,dwAddr);g_lpWnd->AddLog(strMsg);TRACE(strMsg);CFile file;if(!file.Open(lpwstrPath,CFile::modeRead | CFile::shareDenyNone)){// 打开文件失败CString strLog;strLog.Format(_T(" failed to open file %s . err code=%d."),lpwstrPath,GetLastError());g_lpWnd->AddLog(strLog);TRACE(strLog);bRet = FALSE;}if(bRet){file.Seek(dwOffset, CFile::begin);DWORD dwReadBytes = file.Read(lpBuff,dwBytes);file.Close();}if(lpwstrPath)delete[] lpwstrPath;}// 将数据写入磁盘int nLoop = (dwSecNum+127)/128;for(int i=0;i<nLoop && bRet;i++){int _nSectCnt = 128;if((dwSecNum - i * 128) < 128)_nSectCnt = dwSecNum%128;if(!WriteSectors(g_lpWnd->m_hFile, dwAddr+i*128, lpBuff +i*128*512, _nSectCnt)){strMsg.Format(_T(" write data to disk fail! (disk addr:0x%X, buff offset:%d, sect cnt:%d, err code=%d)."),dwAddr+i*128, i*128*512, _nSectCnt, GetLastError());g_lpWnd->AddLog(strMsg);TRACE(strMsg);bRet = FALSE;break;}}strMsg = bRet?_T("\tdone\n"):_T("\tfail\n");TRACE(strMsg);g_lpWnd->AddLog(strMsg);if(lpBuff)delete[] lpBuff;return 0;}// 从磁盘读取数据int CRunLuaDlg::luaRead(lua_State *L){DWORD dwAddr = lua_tointeger(L,1);DWORD dwSecNum  = lua_tointeger(L,2);const char* lpchData = lua_tostring(L,3);DWORD dwOffset = lua_tointeger(L,4);DWORD dwBytes = dwSecNum * 512;LPBYTE lpBuff = new BYTE[dwBytes];ZeroMemory(lpBuff, dwBytes);if(strcmp(lpchData,"$mem") == 0){ // 如果是从内存读数据char szMsg[512] = { 0 };sprintf_s(szMsg,512,"read disk data to mem (disk addr=0x%X, sect num=%d, mem offset=%d):",dwAddr, dwSecNum, dwOffset);TRACE(szMsg);g_lpWnd->AddLog(szMsg);}else{ // 如果是从文件读数据char szMsg[512] = { 0 };sprintf_s(szMsg,512,"read disk data to file (disk addr=0x%X, sect num=%d, file offset=%d, file name=%s):",dwAddr, dwSecNum, dwOffset, lpchData);TRACE(szMsg);g_lpWnd->AddLog(szMsg);}BOOL bRet = TRUE;/***** 从Sector读取数据 *****/int nLoop=(dwSecNum+127)/128;for(int i=0;i<nLoop && bRet;i++){int _nSectCnt = 128;if((dwSecNum - i * 128) < 128)_nSectCnt = dwSecNum%128;if(!ReadSectors(g_lpWnd->m_hFile, dwAddr + i * 128, lpBuff+(i * 128)*512, _nSectCnt)){char szMsg[512] = { 0 };sprintf_s(szMsg,512," read data from disk fail! (disk addr=0x%X, buff offset=%d, sect cnt=%d, err code=%d).",dwAddr+i * 128,(i * 128)*512,_nSectCnt,GetLastError());TRACE(szMsg);g_lpWnd->AddLog(szMsg);bRet = FALSE;break;}}/**/if(bRet){// 读取数据无误CString strMsg;if(strcmp(lpchData,"$mem") == 0) // 将数据写入内存{if(g_lpWnd->m_lpMemBuff == NULL || (g_lpWnd->m_dwMemSize-dwOffset) < (dwSecNum*512)) // 判断内存是否足够{strMsg.Format(_T(" Mem buffer too small!"));g_lpWnd->AddLog(strMsg);TRACE(strMsg);bRet = FALSE;}else{memcpy(g_lpWnd->m_lpMemBuff+dwOffset,lpBuff,dwSecNum*512);       // 将数据拷贝到内存中}}else                             // 将数据写入文件{LPWSTR lpwstrPath = AnsicToUnicode(lpchData);CFile file;if(!file.Open(lpwstrPath,CFile::modeCreate | CFile::modeNoTruncate |CFile::modeReadWrite | CFile::shareDenyNone)){CString strErr;strErr.Format(_T(" Failed to open file %s, err code=%d."),lpwstrPath,GetLastError());TRACE(strErr);g_lpWnd->AddLog(strErr);bRet = FALSE;}if(bRet){file.Seek(dwOffset, CFile::begin);file.Write(lpBuff,dwBytes);file.Close();}if(lpwstrPath)delete[] lpwstrPath;}}g_lpWnd->AddLog(bRet?_T("\tdone\n"):_T("\tfail\n"));TRACE(bRet?_T("\tdone\n"):_T("\tfail\n"));if(lpBuff)delete[] lpBuff;return bRet;}// 延时int CRunLuaDlg::luaSleep(lua_State *L){int nDelay = lua_tointeger(L,1);CString strMsg;strMsg.Format(_T("Sleep %dms...\n"),nDelay);g_lpWnd->AddLog(strMsg);TRACE(strMsg);Sleep(nDelay);return 0;}// 打开句柄int CRunLuaDlg::luaOpenHandle(lua_State *L){CString strMsg;if(!g_lpWnd->OnOpenDisk()){strMsg.Format(_T("open handle failed, err code=%d\n"),GetLastError());g_lpWnd->AddLog(strMsg);}else{strMsg = _T("open handle\n");g_lpWnd->AddLog(strMsg);}return 0;}// 关闭句柄int CRunLuaDlg::luaCloseHandle(lua_State *L){if(g_lpWnd->m_hFile){CloseHandle(g_lpWnd->m_hFile);g_lpWnd->m_hFile = NULL;}CString strMsg = _T("close handle\n");g_lpWnd->AddLog(strMsg);return 0;}




原创粉丝点击