我爱代码 - 专业游戏安全与逆向论坛

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 62|回复: 0

C++调用LuaJit的Demo

[复制链接]

2388

主题

53

回帖

9187

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
9187
QQ
发表于 5 天前 | 显示全部楼层 |阅读模式

想要查看内容赶紧注册登陆吧!

您需要 登录 才可以下载或查看,没有账号?立即注册

x
头文件

  1. #pragma once

  2. extern "C"
  3. {
  4. #include <luajit/src/lua.h>
  5. #include <luajit/src/lualib.h>
  6. #include <luajit/src/lauxlib.h>
  7. #include <luajit/src/luajit.h>
  8. }

  9. class ScriptVM
  10. {
  11. public:
  12.         ScriptVM();
  13.         ~ScriptVM();

  14.         bool Init();
  15.         void Destroy();
  16.         void ExecuteScriptFile(const char* sScriptName, bool bForceReload = false, bool bAssertOnError = true);
  17.         //void ExecuteScript(const char* sScript, bool bAssertOnError = true);
  18. protected:
  19.         bool LoadFileToBuffer(const std::string& path, std::vector<uint8_t>& buffer);
  20. private:
  21.         lua_State* m_pLua;
  22. };
复制代码

源文件

  1. #include "pch.h"
  2. #include "script_vm.h"

  3. static int wrap_exceptions(lua_State* L, lua_CFunction f)
  4. {
  5.         try
  6.         {
  7.                 return f(L);  // Call wrapped function and return result.
  8.         }
  9.         catch (const char* s)
  10.         {  
  11.                 // Catch and convert exceptions.
  12.                 lua_pushstring(L, s);
  13.         }

  14.         catch (std::exception& e)
  15.         {
  16.                 lua_pushstring(L, e.what());
  17.         }

  18.         catch (...)
  19.         {
  20.                 lua_pushliteral(L, "caught (...)");
  21.         }

  22.         return lua_error(L);  // Rethrow as a Lua error.
  23. }

  24. static void error_msg(bool bUseAssert, const char* pacFmt, ...)
  25. {
  26.         //#if defined(_DEBUG)
  27.         char acTemp[2048];

  28.         va_list args;
  29.         va_start(args, pacFmt);
  30.         vsprintf_s(acTemp, pacFmt, args);
  31.         va_end(args);
  32.         if (bUseAssert)
  33.         {
  34.                 assert(acTemp);
  35.         }
  36.         //#endif
  37. }

  38. void report_last_error(lua_State* pLua, bool bUseAssert)
  39. {
  40.         lua_getglobal(pLua, "_ALERT");
  41.         error_msg(bUseAssert, "%s\n", lua_tostring(pLua, -2));
  42.         error_msg(bUseAssert, "%s\n", lua_tostring(pLua, -1));
  43.         lua_pop(pLua, 2);  /* remove error_msg message and _ALERT */
  44. }

  45. std::string& std_string_format(std::string& _str, const char* _Format, ...)
  46. {
  47.         std::string tmp;

  48.         va_list marker = NULL;
  49.         va_start(marker, _Format);

  50.         size_t num_of_chars = _vscprintf(_Format, marker);

  51.         if (num_of_chars > tmp.capacity())
  52.         {
  53.                 tmp.resize(num_of_chars + 1);
  54.         }

  55.         vsprintf_s((char*)tmp.data(), tmp.capacity(), _Format, marker);

  56.         va_end(marker);

  57.         _str = tmp.c_str();
  58.         return _str;
  59. }

  60. ScriptVM::ScriptVM()
  61. {
  62. }

  63. ScriptVM::~ScriptVM()
  64. {
  65. }

  66. int PrintStringList(lua_State* pLuaState)
  67. {
  68.         luaJIT_setmode(pLuaState, -1, LUAJIT_MODE_ALLFUNC | LUAJIT_MODE_ALLSUBFUNC | LUAJIT_MODE_ON);
  69.         // Get the number of strings

  70.         int iStringCount = lua_gettop(pLuaState);

  71.         // Loop through each string and print it, followed by a newline

  72.         for (int iCurrStringIndex = 1; iCurrStringIndex <= iStringCount; ++iCurrStringIndex)
  73.         {
  74.                 // First make sure that the current parameter on the stack is a string

  75.                 if (!lua_isstring(pLuaState, 1))
  76.                 {
  77.                         // If not, print an error

  78.                         lua_error(pLuaState);
  79.                 }
  80.                 else
  81.                 {
  82.                         // Otherwise, print a tab, the string, and finally a newline

  83.                         printf("\t");
  84.                         printf(lua_tostring(pLuaState, iCurrStringIndex));
  85.                         printf("\n");
  86.                 }
  87.         }

  88.         // Return zero, as this function does not return any results

  89.         return 0;
  90. }

  91. bool ScriptVM::Init()
  92. {
  93.         m_pLua = luaL_newstate();

  94.         lua_cpcall(m_pLua, luaopen_base, 0);

  95.         lua_cpcall(m_pLua, luaopen_io, 0);

  96.         lua_cpcall(m_pLua, luaopen_string, 0);

  97.         lua_cpcall(m_pLua, luaopen_table, 0);

  98.         lua_cpcall(m_pLua, luaopen_math, 0);

  99.         lua_cpcall(m_pLua, luaopen_debug, 0);

  100.         lua_cpcall(m_pLua, luaopen_os, 0);

  101.         lua_cpcall(m_pLua, luaopen_package, 0);

  102.         //luaopen_base(m_pLua);

  103.         //luaopen_io(m_pLua);

  104.         //luaopen_table(m_pLua);

  105.         //luaopen_math(m_pLua);

  106.         //luaopen_string(m_pLua);

  107.         //luaopen_debug(m_pLua);

  108.         //tolua_open_binding(m_pLua);

  109.         //lua_setgcthreshold(m_pLua, 200); //200k garbage collection threshold

  110.         lua_register(m_pLua, "PrintStringList", PrintStringList);

  111.         //lua_register(m_pLua, "dofile", OverrideDofile);

  112.         // 添加 LuaJIT 的支持
  113.         lua_pushlightuserdata(m_pLua, (void*)wrap_exceptions);
  114.         luaJIT_setmode(m_pLua, 0, LUAJIT_MODE_ENGINE | LUAJIT_MODE_ON);

  115.         return true;
  116. }

  117. void ScriptVM::Destroy()
  118. {
  119.         lua_close(m_pLua);
  120. }

  121. bool ScriptVM::LoadFileToBuffer(const std::string& path, std::vector<uint8_t>& buffer)
  122. {
  123.         std::ifstream file(path, std::ios::binary | std::ios::ate);
  124.         if (!file.is_open())
  125.                 return false;

  126.         std::streamsize size = file.tellg();
  127.         if (size <= 0)
  128.                 return false;

  129.         buffer.resize(static_cast<size_t>(size));
  130.         file.seekg(0, std::ios::beg);
  131.         if (!file.read(reinterpret_cast<char*>(buffer.data()), size))
  132.                 return false;

  133.         return true;
  134. }


  135. void ScriptVM::ExecuteScriptFile(const char* sScriptName, bool bForceReload /* = false*/, bool bAssertOnError /*= true*/)
  136. {
  137.          // 添加 LuaJIT 的支持
  138.          luaJIT_setmode(m_pLua, -1, LUAJIT_MODE_ALLFUNC | LUAJIT_MODE_ALLSUBFUNC | LUAJIT_MODE_ON);

  139.          int nSize1 = lua_gettop(m_pLua);
  140.          //get chunk name as modified script name
  141.          std::string sChunkName(sScriptName);
  142.          for (unsigned int i = 0; i < sChunkName.length(); i++)
  143.          {
  144.                  if (sChunkName[i] == '/' || sChunkName[i] == '.')
  145.                          sChunkName[i] = '_';
  146.          }

  147.          //get the chunk global
  148.          lua_getglobal(m_pLua, sChunkName.c_str());
  149.          if (bForceReload || !lua_isfunction(m_pLua, -1))//if force reload or not found
  150.          {
  151.                  //load it first
  152.                 std::vector<uint8_t> Buffer;

  153.                  if (LoadFileToBuffer(sScriptName, Buffer))
  154.                  {
  155.                          luaL_loadbuffer(m_pLua, (char*)Buffer.data(), Buffer.size(), sScriptName);

  156.                          //            luaL_loadfile(m_pLua, sScriptName);
  157.                          lua_setglobal(m_pLua, sChunkName.c_str());
  158.                          lua_getglobal(m_pLua, sChunkName.c_str());
  159.                  }
  160.                  else
  161.                          goto failed;
  162.          }

  163.          if (lua_pcall(m_pLua, 0, 0, 0) != 0)
  164.          {
  165.                  error_msg(bAssertOnError, "error executing script file %s: ", sScriptName);
  166.                  report_last_error(m_pLua, bAssertOnError);
  167.          }

  168. failed:
  169.          lua_settop(m_pLua, nSize1);
  170. }

  171. //
  172. // void ScriptVM::ExecuteScript(const char* sScript, bool bAssertOnError)
  173. // {
  174. //         // 添加 LuaJIT 的支持
  175. //         luaJIT_setmode(m_pLua, -1, LUAJIT_MODE_ALLFUNC | LUAJIT_MODE_ALLSUBFUNC | LUAJIT_MODE_ON);
  176. //
  177. //         int status = luaL_loadbuffer(m_pLua, sScript, strlen(sScript), sScript);
  178. //
  179. //         if (status)
  180. //         {
  181. //                 //report_last_error(m_pLua, bAssertOnError);
  182. //         }
  183. //         else
  184. //         {
  185. //                 status = lua_pcall(m_pLua, 0, LUA_MULTRET, 0);  /* call main */
  186. //
  187. //                 //if (status)
  188. //                 //        report_last_error(m_pLua, bAssertOnError);
  189. //         }
  190. // }
  191. //
  192. // bool ScriptVM::ExecuteScriptFunc(const std::vector<const char*>& modules, const char* func, bool bAllowNonexist, const char* sig, ...)
  193. // {
  194. //         // 添加 LuaJIT 的支持
  195. //         luaJIT_setmode(m_pLua, -1, LUAJIT_MODE_ALLFUNC | LUAJIT_MODE_ALLSUBFUNC | LUAJIT_MODE_ON);
  196. //
  197. //         bool bIsSuccess = false;
  198. //
  199. //         //PROFILE("ExecuteScriptFunc");
  200. //
  201. //         int nSize1 = lua_gettop(m_pLua);
  202. //
  203. //         //debug
  204. //
  205. // #if DEBUG_STACK
  206. //         printf("debug lua: stack size before ExecuteScriptFunc = %d\n", nSize1);
  207. // #endif
  208. //
  209. //         va_list    vl;
  210. //         int    narg, nres;    /* number of arguments and results */
  211. //         va_start(vl, sig);
  212. //
  213. //         //get the actual function
  214. //         if (modules.empty()) //func is global
  215. //         {
  216. //                 lua_getglobal(m_pLua, func);
  217. //
  218. //                 if (!lua_isfunction(m_pLua, -1))
  219. //                 {
  220. //                         if (!bAllowNonexist)
  221. //                                 error_msg(true, "ExecuteScriptFunc: Invalid function name: %s\n", func);
  222. //
  223. //                         goto failed;
  224. //                 }
  225. //         }
  226. //         else
  227. //         {
  228. //
  229. //                 //trace down the modules
  230. //
  231. //                 std::vector<const char*>::const_iterator it = modules.begin();
  232. //
  233. //                 //get the global module name or the actual function name if there is no module
  234. //
  235. //                 lua_getglobal(m_pLua, *it);
  236. //
  237. //                 if (!lua_istable(m_pLua, -1))
  238. //
  239. //                 {
  240. //
  241. //                         if (!bAllowNonexist)
  242. //
  243. //                                 error_msg(true, "ExecuteScriptFunc: Invalid table name: %s\n", *it);
  244. //
  245. //                         goto failed;
  246. //
  247. //                 }
  248. //
  249. //
  250. //
  251. //                 for (++it; it != modules.end(); ++it)
  252. //
  253. //                 {
  254. //
  255. //                         lua_pushstring(m_pLua, *it);
  256. //
  257. //                         lua_gettable(m_pLua, -2);
  258. //
  259. //                         if (!lua_istable(m_pLua, -1))
  260. //
  261. //                         {
  262. //
  263. //                                 if (!bAllowNonexist)
  264. //
  265. //                                         error_msg(true, "ExecuteScriptFunc: Invalid table name: %s\n", *it);
  266. //
  267. //                                 goto failed;
  268. //
  269. //                         }
  270. //
  271. //                 }
  272. //
  273. //                 //get the func
  274. //
  275. //                 lua_pushstring(m_pLua, func);
  276. //
  277. //                 lua_gettable(m_pLua, -2);
  278. //
  279. //                 if (!lua_isfunction(m_pLua, -1))
  280. //
  281. //                 {
  282. //
  283. //                         if (!bAllowNonexist)
  284. //
  285. //                                 error_msg(true, "ExecuteScriptFunc: Invalid function name: %s\n", func);
  286. //
  287. //                         goto failed;
  288. //
  289. //                 }
  290. //
  291. //         }
  292. //
  293. //
  294. //
  295. //         /* push    arguments */
  296. //
  297. //         narg = 0;
  298. //
  299. //         while (*sig) { /* push arguments    */
  300. //
  301. //                 switch (*sig++) {
  302. //
  303. //                 case 'd': /* double    argument */
  304. //
  305. //                 case 'f': /* float    argument */    // NieXu: Treat float as double, same as printf()
  306. //
  307. //                         lua_pushnumber(m_pLua, va_arg(vl, double));
  308. //
  309. //                         break;
  310. //
  311. //                 case 'i': /* int argument */
  312. //
  313. //                         lua_pushnumber(m_pLua, va_arg(vl, int));
  314. //
  315. //                         break;
  316. //
  317. //                 case 's': /* string    argument */
  318. //
  319. //                         lua_pushstring(m_pLua, va_arg(vl, char*));
  320. //
  321. //                         break;
  322. //
  323. //                 case 'b': /* boolean argument */
  324. //
  325. //                         lua_pushboolean(m_pLua, va_arg(vl, bool));
  326. //
  327. //                         break;
  328. //
  329. //                 case 'u': /* light user data */
  330. //
  331. //                         lua_pushlightuserdata(m_pLua, va_arg(vl, void*));
  332. //
  333. //                         break;
  334. //
  335. //                 case 't': /* type user data */
  336. //
  337. //                 {
  338. //
  339. //                         void* pData = va_arg(vl, void*);
  340. //
  341. //                         const char* sType = va_arg(vl, const char*);
  342. //
  343. //                         tolua_pushusertype(m_pLua, pData, sType);
  344. //
  345. //                         break;
  346. //
  347. //                 }
  348. //
  349. //
  350. //
  351. //                 case '>':
  352. //
  353. //                         goto endwhile;
  354. //
  355. //                 default:
  356. //
  357. //                         error_msg(true, "invalid option (%c)\n", *(sig - 1));
  358. //
  359. //                         goto failed;
  360. //
  361. //                 }
  362. //
  363. //                 narg++;
  364. //
  365. //                 luaL_checkstack(m_pLua, 1, "too many    arguments");
  366. //
  367. //         }endwhile:
  368. //
  369. //         /* do the call */
  370. //
  371. //         nres = strlen(sig);    /* number of expected results */
  372. //
  373. //         if (lua_pcall(m_pLua, narg, nres, 0) != 0) /* do    the    call */
  374. //
  375. //         {
  376. //
  377. //                 report_last_error(m_pLua, true);
  378. //
  379. //                 goto failed;
  380. //
  381. //         }
  382. //
  383. //         /* retrieve    results    */
  384. //
  385. //         nres = -nres; /* stack index of    first result */
  386. //
  387. //         while (*sig)
  388. //
  389. //         { /* get results */
  390. //
  391. //                 switch (*sig++)
  392. //
  393. //                 {
  394. //
  395. //                 case 'd': /* double    result */
  396. //
  397. //                         if (!lua_isnumber(m_pLua, nres))
  398. //
  399. //                                 error_msg(true, "wrong    result type,function name: %s\n", func);
  400. //
  401. //                         *va_arg(vl, double*) = lua_tonumber(m_pLua, nres);
  402. //
  403. //                         break;
  404. //
  405. //                 case 'f': /* float    result */
  406. //
  407. //                         if (!lua_isnumber(m_pLua, nres))
  408. //
  409. //                                 error_msg(true, "wrong    result type,function name: %s\n", func);
  410. //
  411. //                         *va_arg(vl, float*) = (float)lua_tonumber(m_pLua, nres);
  412. //
  413. //                         break;
  414. //
  415. //                 case 'i': /* int result    */
  416. //
  417. //                         if (!lua_isnumber(m_pLua, nres))
  418. //
  419. //                                 error_msg(true, "wrong    result type,function name: %s\n", func);
  420. //
  421. //                         *va_arg(vl, int*) = (int)lua_tonumber(m_pLua, nres);
  422. //
  423. //                         break;
  424. //
  425. //                 case 's': /* string    result */
  426. //
  427. //                         if (!lua_isstring(m_pLua, nres))
  428. //
  429. //                                 error_msg(true, "wrong    result type,function name: %s\n", func);
  430. //
  431. //                         *va_arg(vl, std::string*) = lua_tostring(m_pLua, nres);
  432. //
  433. //                         break;
  434. //
  435. //                 case 'b': /* boolean argument */
  436. //
  437. //                         if (!lua_isboolean(m_pLua, nres))
  438. //
  439. //                                 error_msg(true, "wrong    result type,function name: %s\n", func);
  440. //
  441. //                         *va_arg(vl, bool*) = (0 != lua_toboolean(m_pLua, nres));
  442. //
  443. //                         break;
  444. //
  445. //                 case 'u': /* light user data */
  446. //
  447. //                         if (!lua_isuserdata(m_pLua, nres))
  448. //
  449. //                                 error_msg(true, "wrong    result type,function name: %s\n", func);
  450. //
  451. //                         *va_arg(vl, void**) = lua_touserdata(m_pLua, nres);
  452. //
  453. //                         break;
  454. //
  455. //                 default:
  456. //
  457. //                         error_msg(true, "invalid option (%c)\n", *(sig - 1));
  458. //
  459. //                 }
  460. //
  461. //                 nres++;
  462. //
  463. //         }
  464. //
  465. //
  466. //
  467. //         bIsSuccess = true;
  468. //
  469. // failed:
  470. //
  471. //         va_end(vl);
  472. //
  473. //         //clear the stack
  474. //
  475. //         lua_settop(m_pLua, nSize1);
  476. //
  477. //
  478. //
  479. // #if DEBUG_STACK
  480. //
  481. //         //debug
  482. //
  483. //         int nSize2 = lua_gettop(m_pLua);
  484. //
  485. //         printf("debug lua: stack size after ExecuteScriptFunc = %d\n", nSize2);
  486. //
  487. //         if (nSize1 != nSize2)
  488. //
  489. //                 stackDump(m_pLua);
  490. //
  491. // #endif
  492. //
  493. //         return bIsSuccess;
  494. // }
复制代码


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|我爱代码 - 专业游戏安全与逆向论坛 ( 陇ICP备17000105号-1 )

GMT+8, 2025-11-3 12:26 , Processed in 0.045996 second(s), 22 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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