我正在尝试使用外星人来调用 Win32 函数。我试过这段代码,但它崩溃了,我不明白为什么。
require( "alien" )
local f = alien.Kernel32.ExpandEnvironmentStringsA
f:types( "int", "string", "pointer", "int" )
local buffer = alien.buffer( 512 )
f( "%USERPROFILE%", 0, 512 )
这是一个很好的问题,对我来说,这是一个测试外星人的机会......
如果你不介意,我借此机会解释如何使用 Alien,所以像我这样(不太习惯require
)偶然发现这个线程的人会开始......
你给了 LuaForge 页面的链接,我去了那里,发现我需要 LuaRock 来获取它。:-( 总有一天我应该安装后者,但我现在选择跳过它。所以我去了存储库并下载了alien-0.4.1-1.win32-x86.rock。我发现它是一个普通的 Zip文件,我可以像往常一样解压缩。
在摸索了一下之后require
,我结束了破解 Lua 脚本中的路径以进行快速测试。我应该创建LUA_PATH
并LUA_CPATH
在我的环境中,我稍后会这样做。
所以我从解压后的文件夹中取出了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]]
然后我尝试了一个简单、简洁的功能,并立即获得视觉结果:MessageBox。
local mb = alien.User32.MessageBoxA
mb:types{ 'long', 'long', 'string', 'string', 'long' }
print(mb(0, "Hello World!", "Cliché", 64))
是的,我收到了消息框!但是单击确定后,我遇到了 Lua 崩溃,可能和您一样。在快速浏览 Alien 文档后,我发现了(未命名的)罪魁祸首:我们需要使用 Windows API 的 stdcall 调用约定:
mb:types{ ret = 'long', abi = 'stdcall', 'long', 'string', 'string', 'long' }
因此,让您的工作变得微不足道:
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))
注意我将缓冲区参数放在 eev 调用中......