tags:

views:

1228

answers:

2

I'm trying to use alien to call Win32 functions. I tried this code, but it crashes and I don't understand why.

require( "alien" )

local f = alien.Kernel32.ExpandEnvironmentStringsA
f:types( "int", "string", "pointer", "int" )
local buffer = alien.buffer( 512 )
f( "%USERPROFILE%", 0, 512 )
+4  A: 

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...

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.

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.

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!):

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.

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:

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...

PhiLho
Great! You could also use Lua for Windows (http://luaforwindows.luaforge.net/). It comes with alien working out of the box.
Jazz
Yes, but although it is a nice package, I don't like its "all batteries included" philosophy, resulting in a download bigger than Python's...
PhiLho
A: 

Hardly fair to compare against python, when python doesnt have all of those capabilities in a single package. Additional to that Lua for Windows has all debugging/profiling/editing tools as well - it is a truly complete development env. Again hardly even close comparison. At 16MB for all that, I doubt you could do similar with python without compromising feature sets and tools. And remembering too LfW has all doc + examples for all modules. doesnt get much more complete, easily the best package I have used for any scripting system.

Grover