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 ) 的行为与 luaL_check* 在任意类型 T 上的行为相同。 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
};

最近更改 · 偏好设置
编辑 · 历史记录
最后编辑于 2016 年 8 月 6 日上午 11:16 GMT (差异)