11
It is a good question as it is, for me, an opportunity to test out Alien...
这是一个很好的问题,因为对我来说,这是一个测试外星人的机会......
If you don't mind, I take the opportunity to explain how to use Alien, so people like me (not very used to require
) stumbling upon this thread will get started...
如果你不介意,我借此机会解释如何使用Alien,所以像我这样的人(不太习惯要求)绊倒这个线程就会开始......
You give the link to the LuaForge page, I went there, and saw I needed LuaRock to get it. :-( I should install the latter someday, but I chose to skip that for now. So I went to the repository and downloaded the alien-0.4.1-1.win32-x86.rock. I found out it was a plain Zip file, which I could unzip as usual.
你给了LuaForge页面的链接,我去了那里,看到我需要LuaRock才能得到它。 :-(我有一天应该安装后者,但我现在选择跳过它。所以我去了存储库并下载了外星人-0.4.1-1.win32-x86.rock。我发现它是一个简单的Zip文件,我可以照常解压缩。
After fumbling a bit with require
, I ended hacking the paths in the Lua script for a quick test. I should create LUA_PATH
and LUA_CPATH
in my environment instead, I will do that later.
在摸索了一下需要之后,我结束了在Lua脚本中的路径进行快速测试。我应该在我的环境中创建LUA_PATH和LUA_CPATH,我稍后会这样做。
So I took alien.lua, core.dll and struct.dll from the unzipped folders and put them under a directory named Alien in a common library repository.
And I added the following lines to the start of my script (bad hack warning!):
所以我从解压缩的文件夹中取出了alien.lua,core.dll和struct.dll,并将它们放在一个公共库存储库中名为Alien的目录下。我在脚本的开头添加了以下行(糟糕的黑客警告!):
package.path = 'C:/PrgCmdLine/Tecgraf/lib/?.lua;' .. package.path
package.cpath = 'C:/PrgCmdLine/Tecgraf/lib/?.dll;' .. package.path
require[[Alien/alien]]
Then I tried it with a simple, no-frills function with immediate visual result: MessageBox.
然后我尝试使用一个简单的,没有多余功能的立即可视结果:MessageBox。
local mb = alien.User32.MessageBoxA
mb:types{ 'long', 'long', 'string', 'string', 'long' }
print(mb(0, "Hello World!", "Cliché", 64))
Yes, I got the message box! But upon clicking OK, I got a crash of Lua, probably like you. After a quick scan of the Alien docs, I found out the (unnamed) culprit: we need to use the stdcall calling convention for the Windows API:
是的,我收到了消息框!但点击确定后,我得到了Lua的崩溃,可能和你一样。在快速浏览Alien文档后,我发现了(未命名的)罪魁祸首:我们需要使用Windows API的stdcall调用约定:
mb:types{ ret = 'long', abi = 'stdcall', 'long', 'string', 'string', 'long' }
So it was trivial to make your call to work:
所以打电话工作是微不足道的:
local eev = alien.Kernel32.ExpandEnvironmentStringsA
eev:types{ ret = "long", abi = 'stdcall', "string", "pointer", "long" }
local buffer = alien.buffer(512)
eev("%USERPROFILE%", buffer, 512)
print(tostring(buffer))
Note I put the buffer parameter in the eev call...
注意我把缓冲参数放在eev调用中......