2016-05-12 7 views
1

XMLファイルの一部であるlua関数を実行する必要があります。私はXMLを解析し、関数全体を文字列として読み込みます。文字列からLua関数を実行する

lua_pcall実行しようとすると、attempt to call a nil valueと表示されます。 しかし、私は関数の部分を削除しようとし、内部のロジックだけを使用して、それは私にうまく働いた。私は機能として実行するために追加のステップを実行する必要があるかどうかを理解する必要があります。

初期化:作業

/* the Lua interpreter */ 
lua_State *luaState; 
// initialize Lua 
luaState = luaL_newstate(); 
lua_register(luaState, "getValue", get_value); 
lua_register(luaState, "setValue", set_value); 
// load Lua base libraries 
luaL_openlibs(luaState); 

: XML

-- lua script to be executed by this algorithm 
-- use following API calls to get and set function block data 
-- local IN1 = getValue("IN1") 
-- setValue("OUT1", value) 
setValue("RequestAccepted", "true"); 

-- lua script 

C++コード:

TAlgoTable::iterator iter = algoTable.find("RequestAccepted"); 
if (luaL_dostring(luaState, iter->second.c_str())) 
{ 
    printf("Failure at Algorithm : 'RequestAccepted' Reason : %s", lua_tostring(luaState, -1)); 
} 

が機能していない:

-- lua script to be executed by this algorithm 
function RequestAccepted() 
-- use following API calls to get and set function block data 
-- local IN1 = getValue("IN1") 
-- setValue("OUT1", value) 
setValue("RequestAccepted", "true"); 

end -- lua script 

C++コード:

lua_getglobal(luaState, "RequestAccepted"); // function to be called 
if (lua_pcall(luaState, 0, 0, 0)) { 
    printf("Failure at Algorithm : 'RequestAccepted' Reason : %s", lua_tostring(luaState, -1)); 
} 
+0

最初の例では、 'lua_dostring()'を呼び出してLuaコードを解析して実行します。 2番目の例では、あなたはそのビットを残していない限り、そうではありません。 – md5i

答えて

1

Iが見つかりました。私はバッファに機能をロードする必要があることを理解しました。

int SParamSchemaNode::parseScript(lua_State* L, 
            const char* arglist, 
            const char* body) 
{ 
std::ostringstream bufToParse; 

// save old stack top so we can clean up errors from the first 
// try if the second succeeds 
int oldStackTop = lua_gettop(L); 
bufToParse << "return function(" << arglist << ") return (" 
      << body << ") end"; 
if (luaL_dostring(L, bufToParse.str().c_str())) 
{ 
    int parseError1_pos = lua_gettop(L); 
    bufToParse.str(std::string()); // reset bufToParse string to empty 
    bufToParse << "return function(" << arglist << ") " 
       << body << " end"; 
    if (luaL_dostring(L, bufToParse.str().c_str())) 
    { 
     // since the error message includes the script which we're trying 
     // to parse, the result has unbounded length; so use another 
     // ostringstream to hold the error message 
     std::ostringstream errmsg; 
     errmsg << "Errors parsing the following script:" << std::endl; 
     errmsg << body << std::endl << std::endl; 
     errmsg << "Parser error when interpreting as an expression:" << std::endl; 
     errmsg << lua_tostring(L, parseError1_pos) << std::endl << std::endl; 
     errmsg << "Parser error when interpreting as a function body:" << std::endl; 
     errmsg << lua_tostring(L, -1); 
     ERROR_ReportError(errmsg.str().c_str()); 
    } 
} 
if (DEBUG) 
{ 
    std::cout << "Successfully loaded chunk: " << bufToParse.str() << std::endl; 
} 
int ref = luaL_ref(L, LUA_REGISTRYINDEX); 
lua_settop(L, oldStackTop); 
return ref; 
} 

を次に: 下記のリンクは、私は、私のプロジェクトの一つで、私はこれをしなかった方法を http://gouthamanbalaraman.com/blog/minimal-example-lua-function-cpp.html

0

を解決するために(コピー&ペースト、書式設定を許し)を使用して、Luaの参照を作成した役立ちました私はSParameterDefinition::m_applicableScriptRefメンバー(例えば)でこれを保存し、使用してそれを呼ばれる:

bool SParameterDefinition::isApplicable(SAbstractComponent* cmpt, int index) 
{ 
if (m_applicableScriptRef == LUA_NOREF) 
{ 
    return true; 
} 

lua_State* L = schema()->luaState(); 
// fetch the function to call from the registry 
lua_rawgeti(L, LUA_REGISTRYINDEX, m_applicableScriptRef); 
// push the "cmpt" argument 
SWIG_UC_push_SAbstractComponent(L, cmpt); 
int nargs = 1; 
if (m_isInstanced) 
{ 
    lua_pushnumber(L, index); 
    nargs++; 
} 
// protected call of the function (nargs arguments, 1 result, 
// no special error handler function) 
int script_result = lua_pcall(L, nargs, 1, 0); 
if (script_result != 0) 
{ 
    std::ostringstream errmsgBuf; 
    errmsgBuf << "Error while calling applicable script for " 
       << "parameter " << m_name << ":\n"; 
    errmsgBuf << lua_tostring(L, -1); 
    ERROR_ReportError(errmsgBuf.str().c_str()); 
} 
if (! lua_isboolean(L, -1)) 
{ 
    report_type_error("Applicable", 
         m_name.c_str(), "boolean", 
         luaL_typename(L, -1)); 
} 
bool result = (lua_toboolean(L, -1) != 0); 
lua_pop(L, 1); 
return result; 
} 

あなたがここに完全な複雑さを必要としないかもしれないが、基本的なポイントは0123で身体を包むされていますを入力し、luaL_dostringと評価し、そのスクリプトの結果をluaL_ref(L, LUA_REGISTRYINDEX)で保存します。

関連する問題