自己流Luaのクラス定義
自分の使っているLuaのクラス実装は以下の機能を持つすごいやつ
投げやりの文章だが睡魔が襲ってきたのでやむなし。実装例は上げておくので詳しい解説は明日以降にする。
LuaJIT(2.0.5)のlua_pcall()でアクセス違反がでる問題について
おそらく他にも引っ掛かった人が居そうなので投稿。
以下のコードを見ていただきたい。
C言語
#include <stdio.h> #include <lua.hpp> /* Lua専用関数. */ int luaF_CFunction(lua_State* L) { const char* str = luaL_checkstring(L,1); printf("%s\(・ ・ ))゜ しまりん", str); return 1; } int main() { // Luaステートの作成 lua_State* L = luaL_newstate(); luaL_openlibs(L); // スクリプトファイルの読み込み if( luaL_loadfile(L, "script.lua") || lua_pcall(L, 0, 0, 0) ) { printf("%s\n", lua_tostring(L,lua_gettop(L))); } // Cの関数の登録 static const struct luaL_Reg fs[] { {"CFunction", &luaF_CFunction}, {nullptr,nullptr} }; luaL_register(L, "MyLib", fs); /* -- Luaの関数呼び出し(今日の主役) -- */ lua_getglobal(L,"main"); if( lua_pcall(L, 0, 0, 0)!=0 ) { printf("%s\n", lua_tostring(L, lua_gettop(L))); } getchar(); // 後始末 lua_close(L); return 0; }
Lua
function main() -- C言語の関数呼び出し MyLib.CFunction("なでしこ ( >ワ<)ノ") end
一見すると何の変哲もないソースコード。ただLua側からC言語の関数を呼び出して終わるだけのもの。
こいつがでるまでは...
その名も「アクセス違反」。自分の場合はゲームエンジンへの組み込みテスト中にこれが起こった。デバックしてみると関数の呼び出し自体は成功している模様。
急遽別途のプロジェクトを作成して同じものを動かしてみると、なぜかこっちは通常どおり動作する。
ネットを開きあれやこれや.....
原因
結論からいうとLuaJITでかつx64で動作させた場合のみこれが起こる。根本的な原因は不明だが、どうやらLuaJITはもともとx64上で問題を抱えていることと、ガーベッジコレクションが関係しているらしい。*1*2。
対処法
x64を使わない
比較的簡単にできてリスクも少なくて済む。しかし、x64上での動作を余儀なくされる場合にはあまり意味をなさない。
コンパイラオプションの変更
以下のオプションでライブラリをビルドする。
msvcbuild gc64
これでひとまずは、アクセス違反が発生しなくなった。ただ、詳細な検証を行っていないため今後別の問題が発生するかどうかはわからない。
はじめまして、開設です。
ふと思いついたアイディアを書き留めたいと思い、ブログをはじめました。
低浮上になりますが、よろしくお願いします。