Luna Wrap

lua-users home
wiki

這段程式碼旨於大量簡化 C++ 與 Lua 之間的互動。也就是說,它提供了

下載

LunaWrap 附帶 5 個檔案,因此已打包到 ZIP 檔案中:[LunaWrap.zip] 注意:我已將所有檔案複製出自己的專案,這表示我尚未單獨測試它們。這反過來表示它可能無法編譯,但我將盡快測試並修正所有檔案。

check<T>、lightcheck<T>、is_a<T> 和 push 的用法

LunaWrap::check( lua_State* state , int index ) 在任意型別 T 上的行為就像 luaL_check*。LunaWrap::lightcheck<T>( lua_State* state , int index , T fallback = T() ) 會檢查堆疊位置上是否為必要的數值,然後回傳它。如果不是,它會回傳指定預設值的第三個參數。LunaWrap::is_a<T>( lua_State* state , int index ) 會回傳 true(如果提供的堆疊位置上的數值是 T)或 false(反之)。透過使用 LunaWrap::push( lua_State* state , ... ),您可以透過 ... 推送任意數量的 C++ 型別,而 push() 會永遠回傳堆疊上已推入的 lua 值數。這樣,您可以輕鬆地執行

int foo( lua_State* state ){ return LunaWrap::push( state , 5 , std::string("Hello World") , std::map<int,int>() ); 

LunaWrapFunc?() 巨集的用法

下列範例具備廣為人知的 Account 類別。請注意,您不再需要撰寫 Lua「代理」函式,因為它們會由 LunaWrap 為您產生。這裡所說的「代理」函式是指那些會使用 lua_State*、從 lua 堆疊上讀取 C++ 函式的所有參數、呼叫實際 C++ 函式並回傳它回傳的值個數(通常為 1)的函式。您真的可以立刻在 Lua 中開始使用您的 C++ 類別!

#include "Luna.h"
#include "LunaWrapFunc.h"

class Account
{
    private:

        int balance;

    public:

        Account() : balance( 0 ) {}

        void deposit( int amount ){
            if( amount >= 0 )
                balance += amount;
        }

        int withdraw( int amount ){
            if( balance < amount )
                amount = balance;
            balance -= amount;
            return amount;
        }

        int balance() const {
            return balance;
        }
        
        //! Lua!//
        static const char className[];
        static Luna<Account>::FunctionType methods[];
        static Luna<Account>::PropertyType properties[];
};

const char Account::className[] = "Account";

Luna<Account>::FunctionType Account::methods[] = {
    { "deposit" , LunaWrapFunc( &Account::deposit ) },
    { "withdraw" , LunaWrapFunc( &Account::withdraw ) }
};

Luna<Account>::PropertyType Account::properties[] = {
    { "balance", LunaWrapFunc( &Account::balance ) , 0 } // Readonly property
};

如果您真的有一個「代理」類別,也就是說,您透過 Luna 註冊的一個類別,而它實際上只是一個您提供給 lua 的 C++ 類別的參考,則仍然可以使用 LunaWrapFunc?:您只需在代理類別中提供一個轉型運算子,轉換至實際類別。由於那聽起來比實際情況要更模糊,因此我們也提供一個範例來說明。

#include "Luna.h"
#include "LunaWrapFunc.h"

class StringRef : public std::shared_ptr<std::string>
{
    public:
    
        // Cast-operator to the string object this class "proxies"
        operator string&(){ return *(*this) ); }
        
        //! Lua!//
        static const char className[];
        static Luna<Account>::FunctionType methods[];
        static Luna<Account>::PropertyType properties[];
};

const char StringRef::className[] = "StringRef";

Luna<StringRef>::FunctionType StringRef::methods[] = {
    { "front" , LunaWrapFunc( (char&(string::*)()) &string::front , StringRef ) }, // The cast is needed to disambiguate the const-version front() from the non-const version
    { "back" , LunaWrapFunc( (char&(string::*)()) &string::back , StringRef ) }, // Same here
    { "push_back" , LunaWrapFunc( (char&(string::*)()) &string::back , StringRef ) }
};

Luna<StringRef>::PropertyType StringRef::properties[] = {
    { "length" , LunaWrapFunc( &string::length , StringRef ) , 0 } // Readonly property
};

RecentChanges · 偏好設定
編輯 · 歷程記錄
最後編輯時間:2016 年 8 月 6 日上午 11:16 GMT (差異)