C ++を検討するために、次の要点を開発するためのluaの道を結合:
1は、C ++再利用性が強くない
2、コード主導型のビジネス要件スクリプト、C ++での頻繁な更新はそれがより激しいです行うことができ
、通常のマルチLUA、LUAより速く、より簡単な、より軽量で、3
4、C言語はるかに便利な、より少ないスクリプトC ++をぶら下げ、C ++自体は多くの強力なライブラリ自体が持つ非常に便利だった提供していますので、
C ++では埋め込まれたスクリプトは、一般的に次の方法があります。
まず、システムが実際にスクリプト内で実行されます
クラウド風がLUAを達成するように、第2、メインロジック又はC ++、方法を処理LUA制御サービスが、それはまた、そのようなライブラリーのネットワーク部分を使用することができます
ネットワークセクション、CPU集約型、IO集約型はC ++で書かれ、他のスクリプト言語のコントロールに共通のコードは、簡単にデバッグ、容易な需要に対応するため、唯一のコードを少し変更する必要がありますすることができます
LUAスクリプトとC ++ライブラリの多くは、この例では、LuaBridge / LuaBridge.hライブラリを使用しています
C ++クラスluabrigeの最大の役割はtestCallLuaの背中を使用するように登録されています
//头文件里加入:
#include <lua.hpp>
#include <LuaBridge/LuaBridge.h>
luabridgeはhttps://github.com/vinniefalco/LuaBridgeをダウンロードして行くことができます
LUA仮想マシンを作成します。
lua_State* buildLuaEngine(const std::string& file) {
lua_State* L = luaL_newstate();
// need check L
luaL_openlibs(L);
auto ok = reloadLuaScript(L, file);
if(!ok) {
lua_close(L);
L = nullptr;
}
return L;
}
仮想マシンのLUAファクトリクラスを構築するためのluaL_newstate()
デバッグ、文字列IO、数学ライブラリ、テーブル:luaL_openlibsなど(L)負荷Luaのライブラリ。。。
仮想マシンへのreloadLuaScript輸入のluaのluaファイル
lua_close(L)、閉じたLuaのリソース
C ++およびLUAクロスコール:
Luaの呼び出しC ++コードは比較的簡単です:
print("hello i'm in lua");
function testA(a)
print("call c++ part");
globalFunction();
a:action();
a:doPrint(1,2);
end
C ++クラスやメソッドのパラメータへのダイレクトアクセス
より複雑なLUAを呼び出すC ++コード:
登録セクション:
void registerClassAndFucntions(lua_State* L) {
using namespace luabridge;
getGlobalNamespace(L).addFunction("globalFunction", globalFunction);
getGlobalNamespace(L)
.beginClass<A>("A")
.addFunction("action", &A::action)
.addFunction("doPrint", &A::doPrint)
.addFunction("goodMan", &A::goodMan)
.endClass()
.deriveClass<B,A>("B")
.addFunction("hello", &B::hello)
.endClass();
}
この方法により、C ++のクラスと利用可能なLUA何であるかの関数として登録
registerClassAndFucntions:C ++は、登録さLUA仮想マシンです
globalFunctionは、グローバル関数を登録し、globalFunctionを呼んでLUAはC ++ globalFunction呼び出すことです
beginClass クラスに登録する(「A」)を
deriveClassは、派生クラスの生成
登録機能addFunctionを
コール一部:
void testCallLua(lua_State* L) {
A a;
// lua_getglobal(L, "testA");
// luabridge::push(L,&a);
// lua_pcall(L, 1, 0, 0);
B b;
lua_getglobal(L, "testAAndB");
luabridge::push(L, &a);
luabridge::push(L, &b);
lua_pcall(L, 2, 0, 0);
}
lua_getglobal(L、 "テスタ") ; LUAグローバル関数種皮を与える
luabridgeを::プッシュ(L、&); AとA luafunctionパラメータとして
lua_pcall(L、1、0、 0); 1は引数を必要と表す(いくつかのプッシュ、数ヶ月である)、0のリターンに続いて、具体的インターフェイスのLUAに関連するドキュメントを参照して、0エラーと特異的に対処するために戻って、その後、何のパラメータを示していない
ダイレクトでのLUAのコールglobalFunctionを();あなたはCのグローバル関数に取得することができ++
C ++呼び出しLuaのパッケージへのインタフェース:
非常に便利なC ++またはコールLUAでluabrige、二次包装の必要性は、テンプレートでカプセル化することができる
カプセル化した後に呼び出さ
LuaScript script;
script.callLuaScript("testAndB", &a, &b)
オンライン
パーツパッケージコード:
#ifndef FND_LUA_SCRIPT_H
#define FND_LUA_SCRIPT_H
#include <lua.hpp>
#include <LuaBridge/LuaBridge.h>
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <deque>
#include <functional>
#include <mutex>
#include <stdexcept>
#include <string>
#include <thread>
#include <unordered_map>
namespace Yt{
namespace Utility{
class LuaScript {
public:
enum class BacktraceState{
Trace,
Untrace
};
using RegisterFunction = std::function<bool(lua_State*)>;
void init(const std::string& initfile, RegisterFunction func);
bool reload(const std::string& initfile, RegisterFunction func);
bool reload();
~LuaScript();
explicit LuaScript(BacktraceState state, int checkTime,
int singleCallMaxDuration, bool ncheck = false)
:m_isRunning(false),
m_callLuaTimes(0),
m_currentLuaErrorId(0),
m_duration(std::chrono::milliseconds(signleCallMaxDuration)),
m_traceState(state),m_needCheck(ncheck){}
class Exception:public std::runtime_error{
public :
Exception(const std::string& info):std::runtime_error(info.c_str()){}
};
int64_t callLuaTimes() const{ return m_callLuaTimes.load(); }
lua_State* state(){ return m_lua; }
template <class... Param>
void callLuaScript(const std::string& func, Param&&... param) {
if(prepareForLua(func)) {
pushParam(std::forward<Param>(param)...);
luaCallback(func, sizeof...(param));
}
}
template <class... Param>
bool callCondition(bool rev, const std::string& func, Param&&... param) {
if(prepareForLua(func)) {
pushParam(std::forward<Param>(param)...);
return luaCondition(rev, func, sizeof...(param));
}
return rev;
}
//。。。
Luaの動的な更新:
LUA仮想マシンの建物コードは、関数の中にカプセル化されて再構築へのLuaの仮想マシンは、新しいLUAスクリプトは次の呼び出しは、一般的に良い最初の新規建設後に解放され、その後、古い、入って来たときにロードされます
lua_State* buildLuaEngine(const std::string& file) {
lua_State* L = luaL_newstate();
// need check L
luaL_openlibs(L);
auto ok = reloadLuaScript(L, file);
if(!ok) {
lua_close(L);
L = nullptr;
}
return L;
}
その他の使用量参照ドキュメントluabridge
メイクファイル:
main:main.cpp
g++ -I /usr/include/lua5.2 -std=c++11 -o main main.cpp -llua5.2
Linuxのうなずきファイルは、一般的に、それはパスがlua5.2フォルダを追加見つけることが一般的ではありませんので、メイクファイル/usr/include/lua5.2パスを追加するために使用された場合、-Iパラメータがパスを表し、は/ usr /に含めるに配置されています、-llua5.2の文Luaのリンクライブラリ
Luaのファイル:
print("hello i'm in lua");
function testA(a)
print("call c++ part");
globalFunction();
a:action();
a:doPrint(1,2);
end
function testAAndB(a, b)
print("A and B");
globalFunction();
a:action();
a:doPrint(1,2);
b:hello("Good using c++ and Lua");
end
ここでは完全な結合LuaのC ++コードの例です:
#include <lua.hpp>
#include <LuaBridge/LuaBridge.h>
#include <iostream>
#include <string>
class A {
public:
void action() { std::cout << "hello I'm A\n";}
virtual void doPrint(int a, int b) {
std::cout << "in A a : " << a << " b : " << b << std::endl;
}
std::string goodMan() const { return "goodman";}
};
class B : public A {
public:
void hello(const std::string& info) const {
std::cout << "hello: " << info << std::endl;
}
virtual void doPrint(int a, int b) override {
std::cout << "in B just " << (a + b) << std::endl;
}
};
void globalFunction() {
std::cout << "hello this is a global func\n";
}
bool reloadLuaScript(lua_State* L, const std::string& luafile) {
int state = luaL_dofile(L, luafile.c_str());
if(state != LUA_OK) {
// std::cout << "ok";
return false;
}
return true;
}
void registerClassAndFucntions(lua_State* L);
void testCallLua(lua_State* L);
lua_State* buildLuaEngine(const std::string& file) {
lua_State* L = luaL_newstate();
// need check L
luaL_openlibs(L);
auto ok = reloadLuaScript(L, file);
if(!ok) {
lua_close(L);
L = nullptr;
}
return L;
}
int main(int argc, char** argv) {
if(argc != 2) return 1;
std::cout << "try load file " << argv[1] << std::endl;
auto L = buildLuaEngine(argv[1]);
if(L) {
registerClassAndFucntions(L);
testCallLua(L);
}
if(L) {
lua_close(L);
L = nullptr;
}
}
void registerClassAndFucntions(lua_State* L) {
using namespace luabridge;
getGlobalNamespace(L).addFunction("globalFunction", globalFunction);
getGlobalNamespace(L)
.beginClass<A>("A")
.addFunction("action", &A::action)
.addFunction("doPrint", &A::doPrint)
.addFunction("goodMan", &A::goodMan)
.endClass()
.deriveClass<B,A>("B")
.addFunction("hello", &B::hello)
.endClass();
}
void testCallLua(lua_State* L) {
A a;
// lua_getglobal(L, "testA");
// luabridge::push(L,&a);
// lua_pcall(L, 1, 0, 0);
B b;
lua_getglobal(L, "testAAndB");
luabridge::push(L, &a);
luabridge::push(L, &b);
lua_pcall(L, 2, 0, 0);
}