2016-09-08 3 views
3

WindowsでLua dll拡張子を作成しようとしています。私はLua 5.3を使用しています。私のコンパイラはMinGWのもので、gcc 4.9.3です。dll拡張子のロード時にLuaが壊れる

DLL拡張のための私のCコードは次のようなものです:

#include <stdio.h> 
#include <lua.h> 

static int dub(lua_State *L) { 
    const double a = lua_tonumber(L, 1); 
    lua_pushnumber(L, a*2); 
    return 1; 
} 

__declspec(dllexport) int __cdecl luaopen_mylib(lua_State *L){ 
    printf("One\n"); 
    lua_pushcfunction(L, dub); 
    printf("Two\n"); 
    lua_setglobal(L, "dub"); 
    printf("Three\n"); 
    return 1; 
} 

私はこのように私のDLLをコンパイルしています:

gcc mylib.c -shared -o mylib.dll -llua 

私はLuaのからそれをロードすることができているという考えと

require "mylib" 
print (dub(5)) --should print 10 

実際にルアコードを実行しようとすると、でクラッシュします行。 DLLは "One"と "Two"を印刷できますが、クラッシュする前に "Three"を印刷することはありません。これは、問題が 'lua_setglobal'呼び出しである可能性があることを示しています。

どうなりますか?それをさらにデバッグする方法や修正する方法は?

ボーナスに関する質問:luaopen_mylibの戻り値は何ですか?

ありがとうございます!

+0

どのような種類のクラッシュですか?それはLuaからスタックトレースを生成しますか? Cセグメンテーション? – Oka

+0

@Oka Windowsのポップアップメッセージ "lua.exeが動作を停止しました"が表示されます。これにはいくつかの詳細がありますが、何も意味がありません。 – luaboy

+1

私はWindowsデベロッパーではありませんが、その詳細は誰かに何かを意味するかもしれません。ヘルプを探すときは、エラーメッセージやレポートを含めることをお勧めします。 – Oka

答えて

2

コードをコンパイルしても問題ありません。だからあなたの問題はあなたのコードからではありません。私の推測では、異なるバージョンのLuaを使用しているか、リンクが何らかの形で間違っているということです。

バージョンミスマッチが発生する可能性がある箇所は3つあります。 -llua

  • とビルドラインで

      あなた #include <lua.h>ラインで
    1. あなたはlua実行

    を実行すると、これらの3つのすべてが、同じLuaのバージョンであることが重要です。 1つが一致しない場合は、問題が発生する可能性があります。私はあなたのluaの実行可能なバージョンは他のものと一致しないと思います。

    もう1つ試してみると、あなたのDLLはlua dllとリンクする必要があります。あなたのシステムにlua53.dllと呼ばれるファイルがあるはずです。ビルドディレクトリにコピーします。あなたはgccでコンパイルすると、代わりにこれを試してみてください。

    gcc mylib.c -shared -o mylib.dll lua53.dll 
    

    これはあなたのdll拡張子はLuaの実行ファイルが使用している正確に同じLuaのコードを呼び出すことを意味します。彼らはあなたが今それを持っている方法で、-llua行で、あなたが静的にluaでリンクしているようです。これは、lll実行可能ファイルがlua53.dllのコードを呼び出すため、DLLが静的ライブラリで別のコードを呼び出している間に、dllライブラリに必要なことはほとんどありません。私はこれだけであなたのクラッシュを引き起こしているとは思わないが、それは良い習慣ではない。 luaがグローバルな状態を使用している場合(そうではありません)、このリンクの問題があなたのクラッシュを引き起こす可能性があります。また、lua53.dllに対してコンパイルすると、mylib.dllがはるかに小さいことがわかります。

    概要では、クラッシュの原因となっているバージョンの不一致があると思います。また、良いフォームのために静的ライブラリの代わりにlua dllにリンクする必要があります。

    ボーナスの質問:luaopen_mylibの戻り値は何ですか?

    コードには、ではなく実際には0である必要があります。戻り値は、require()コールを返すスタック上に残された数です。あなたのライブラリは、グローバルな状態になり、ルア値を返さないだけです。これを行う別の方法は、ライブラリの関数を含むテーブルを返すことです。そうすれば、あなたは地球の状態を汚染することはありません。あなたのライブラリが一つだけの機能を持っているので、あなたはこのように直接それを返すことができます:

    __declspec(dllexport) int __cdecl luaopen_mylib(lua_State *L){ 
        lua_pushcfunction(L, dub); 
        return 1; 
    } 
    

    その後、としてLUAからそれを使用する:呼び出し側がどのような名前に決定することができますので、私はこの方法を好む

    local dub = require("mylib") 
    print (dub(5)) --should print 10 
    

    グローバルな空間を汚染することはありません。

  • 関連する問題