There is a C code that describes the redirect of the print function from lua (lua5.1.dll) to its handler. Help translate it to Delphi?

#include <iostream> #include "lua.hpp" static int l_my_print(lua_State* L) { int nargs = lua_gettop(L); std::cout << "in my_print:"; for (int i=1; i <= nargs; ++i) { std::cout << lua_tostring(L, i); } std::cout << std::endl; return 0; } static const struct luaL_Reg printlib [] = { {"print", l_my_print}, {NULL, NULL} /* end of array */ }; int main(void) { lua_State* L = luaL_newstate(); luaL_openlibs(L); lua_getglobal(L, "_G"); luaL_setfuncs(L, printlib, 0); Lua_pop(L, 1); luaL_dostring(L, "print(\"Hello from Lua\")"); lua_close(L); return 0; } 

Ps. The wrapper for the LUA took from here https://github.com/danieleteti/lua4delphi

  • 3
    Just today, SO was a request to rewrite to another programming language. I give the answer in my free translation: "If you really need someone to do this work for you, then pay attention to the freelance sites where people get paid for performing such tasks. If you want to complete the task yourself, then don’t Feel free to show already done. And ask more specific questions. " - Ruslan Rakhmanin
  • @Ruslan Rakhmanin Ruslan, DEAR look on the Internet for a joke about programmers, what distinguishes the Russian, Jewish and English forum. No comments. I gave the answer to my question below. - Indy Putny
  • 3
    @IndiPutNiyu no less dear, you are right said. With tasks - to freelance. With the formulated questions - here. I also recommend that you either bring a question to your answer, or vice versa. Because Now you have everything in the "best" form of the Russian forums - They asked A, answered "everything is wrong, do Y". - Kromster

1 answer 1

It is not necessary to rewrite anything, when using the https://github.com/danieleteti/lua4delphi wrapper, you only need to call the function:

 LuaBind.DeclareGlobalFunction('print',printL); 

which redirects the call to the print function to our handler.

and the printL function itself will look like this:

 function printL(L: PLua_State): Integer; cdecl; 

.......

 function printL(L: PLua_State): Integer; var N, I : Integer; S : MarshaledAString; Sz : Size_t; Msg : String; begin Msg := ''; N := lua_gettop(L); //* number of arguments */ lua_getglobal(L, 'tostring'); for I := 1 to N do begin lua_pushvalue(L, -1); //* function to be called */ lua_pushvalue(L, i); //* value to print */ lua_call(L, 1, 1); S := lua_tolstring(L, -1, @Sz); //* get result */ if S = NIL then begin Result := luaL_error(L, '"tostring" must return a string to "print"',[]); Exit; end; if I > 1 then Msg := Msg + #9; Msg := Msg + String(S); lua_pop(L, 1); //* pop result */ end; Result := 0; // тут указываем метод который выведет наше сообщение ХХХХХ.DoPrint(Msg); end; 
  • 2
    If you compare your code with the C code, you can see the discrepancy. In C code, the values ​​of the function arguments are removed sequentially from the stack with the help of lua_tostring(L, i) . You have the global tostring function added to the stack first. Then, for each argument of your print function, it is tostring stack and the tostring function tostring earlier is called. The result of the execution via lua_tolstring(L, -1, @Sz) finally obtained in Delphi. Why 2 times is called tostring , first internal, then external. Why was it impossible to just get the arguments from the stack in C? - Ruslan Rakhmanin
  • By the way, checking for the correct execution of lua_tolstring already useless. If it were, it would have already worked when running the global tostring built into Lua. Or did I read the code? Explain, please. - Ruslan Rakhmanin
  • These two codes are not to be compared. I took the implementation of the print call from a ready-made solution - another project: github.com/Dennis1000/verysimplelua from the file VerySimple.Lua.pas. For comments on the code thank you, I will understand. Ps. At the moment, everything works as planned. - Indie Putny