10

エイリアンを使用して Win32 関数を呼び出そうとしています。このコードを試しましたが、クラッシュしてしまい、その理由がわかりません。

require( "alien" )

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

1 に答える 1

11

私にとってエイリアンを試す機会なので、それは良い質問です...

よろしければ、この機会に Alien の使用方法を説明しますので、私のような (あまり慣れていないrequire) 人々がこのスレッドに出くわすことから始めてください...

あなたは LuaForge ページへのリンクを教えてくれました。私はそこに行って、LuaRock を取得する必要があることを知りました。:-( いつか後者をインストールする必要がありますが、今のところはスキップすることにしました。それで、リポジトリに行き、Alien-0.4.1-1.win32-x86.rockをダウンロードしました。それがプレーンな Zip であることがわかりました。通常どおり解凍できます。

で少し手探りした後require、簡単なテストのために Lua スクリプトのパスをハッキングしました。作成する必要がLUA_PATHありLUA_CPATH、代わりに自分の環境で、後で行います。

そこで、解凍したフォルダーからエイリアン.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))

はい、メッセージボックスを受け取りました!しかし、[OK] をクリックすると、おそらくあなたと同じように、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 呼び出しにバッファー パラメーターを入れました...

于 2008-11-12T16:25:36.860 に答える