<h2>Programming with Lua and or C</h2>

<table border="0" width="100%">
<tr>

<td valign="top" width="300px">
<dl>

<small>
<dt><b>1. Development
<dd>1.1 Introduction</dd>
<dd><a Programming with Lua and or
<dd><a Working with
<dd>1.4 Bmake</dd>
<dd>1.5 Debugging</dd>
<dd>1.6 Using Fossil (DVCS)</dd>
<dd>1.7 Further Reading</dd>
</small>
</br>

</dl>
</td>


<td valign="top">
<h3>Using C Library's in Pure Lua (Simple)</h3>

<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>

<pre><code>
local ffi = require("ffi")
ffi.cdef[[
int printf(const char *fmt, ...);
]]
ffi.C.printf("Hello %s!", "world")

</br>


<h3>Using C Library's in Pure Lua (Advanced)</h3>

<p>The following code shows how to access the zlib compression library from Lua code.</p>

<pre><code>
local ffi = require("ffi")
ffi.cdef[[
unsigned long compressBound(unsigned long sourceLen);
int compress2(uint8_t *dest, unsigned long *destLen,
	      const uint8_t *source, unsigned long sourceLen, int level);
int uncompress(uint8_t *dest, unsigned long *destLen,
	       const uint8_t *source, unsigned long sourceLen);
]]

local zlib = ffi.load(ffi.os == "Windows" and "zlib1" or "z")

</br>


<h3>C++ and Lua Hybrid Application</h3>

<p>The following example uses LuaWrapper and Luajit.

LuaWrapper is a library designed to help bridge the gab between Lua and C++.
It is designed to be small (a single header file), simple, fast, and typesafe.
It has no external dependencies other than the lua library itself, and does not
need to be precompiled; the header can simply be dropped into a project and
used immediately. It even supports class inheritance to a certain degree.
Objects can be created in either Lua or C++, and passed back and forth.
</p>

<p>
The nice thing about LuaWrapper is that we can develop our C++ and Lua
frameworks side by side and still keep them separate.
</p>


<pre><code>#include &ltiostream&gt
extern "C"
{
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
#include "luajit.h"
}

#include "LuaBankAccount.hpp"

using namespace std;

int main(int argc, const char *argv[])
{
    if (argc == 2)
    {
        lua_State* L = luaL_newstate();
        luaJIT_setmode(L, -1, LUAJIT_MODE_WRAPCFUNC|LUAJIT_MODE_ON);
        luaL_openlibs(L);
        luaopen_BankAccount(L);
        if (luaL_dofile(L, argv[1]))
            cout << lua_tostring(L, -1) << endl;
        lua_close(L);
    }
    return 0;
}

</br>


<code><pre>
#include &ltBankAccount.hpp&gt

float BankAccount::s_totalMoneyInBank = 0;

BankAccount::BankAccount(const char* owner, float balance)
    : m_owner(owner)
    , m_balance(balance)
{
    s_totalMoneyInBank += balance;
}

const char* BankAccount::getOwnerName() const
{
    return m_owner;
}

void BankAccount::deposit(float amount)
{
    s_totalMoneyInBank += amount;
    m_balance += amount;
}

void BankAccount::withdraw(float amount)
{
    s_totalMoneyInBank -= amount;
    m_balance -= amount;
}

float BankAccount::checkBalance() const
{
    return m_balance;
}

float BankAccount::checkTotalMoneyInBank()
{
    return s_totalMoneyInBank;
}

</br>


<code><pre>
#ifndef EXAMPLE_HPP_
#define EXAMPLE_HPP_

#include &ltstring&gt
#include &ltiostream&gt

class BankAccount
{
public:
    BankAccount(const char* owner, float balance);

    const char* getOwnerName() const;
    void deposit(float amount);
    void withdraw(float amount);
    float checkBalance() const;

    static float checkTotalMoneyInBank();

private:
    const char* m_owner;
    float m_balance;
    static float s_totalMoneyInBank;
};

#endif EXAMPLE_HPP_

</br>


<code><pre>
#include &ltiostream&gt
#include &ltstring&gt

extern "C"
{
#include "lua.h"
#include "lauxlib.h"
}
#include "luawrapper.hpp"

#include "BankAccount.hpp"

using namespace std;


Allocator

Types that do not have a default contructor require you to write an allocator function.
This function is passed to luaW_register.


BankAccount* BankAccount_new(lua_State *L)
{
    const char* owner = luaL_checkstring(L, 1);
    float balance = luaL_checknumber(L, 2);
    return new BankAccount(owner, balance);
}


Static Functions

These functions can be called directly from the BankAccount table in lua


int BankAccount_checkTotalMoneyInBank(lua_State *L)
{
    lua_pushnumber(L, BankAccount::checkTotalMoneyInBank());
    return 1;
}


Member Functions

These functions are stored on the BankAccount.metatable table.
All BankAccount objects in Lua have access to the functions defined there
by the use of special a __index metatmethod that is set up by LuaWrapper.


int BankAccount_getOwnerName(lua_State *L)
{
    BankAccount* account = luaW_check<BankAccount>(L, 1);
    lua_pushstring(L, account->getOwnerName());
    return 1;
}

int BankAccount_deposit(lua_State *L)
{
    BankAccount* account = luaW_check<BankAccount>(L, 1);
    float amount = luaL_checknumber(L, 2);
    account->deposit(amount);
    return 0;
}

int BankAccount_withdraw(lua_State *L)
{
    BankAccount* account = luaW_check<BankAccount>(L, 1);
    float amount = luaL_checknumber(L, 2);
    account->withdraw(amount);
    return 0;
}

int BankAccount_checkBalance(lua_State *L)
{
    BankAccount* account = luaW_check<BankAccount>(L, 1);
    lua_pushnumber(L, account->checkBalance());
    return 1;
}

static luaL_Reg BankAccount_table[] =
{
    { "checkTotalMoneyInBank", BankAccount_checkTotalMoneyInBank },
    { NULL, NULL }
};

static luaL_Reg BankAccount_metatable[] =
{
    { "getOwnerName", BankAccount_getOwnerName },
    { "deposit", BankAccount_deposit },
    { "withdraw", BankAccount_withdraw },
    { "checkBalance", BankAccount_checkBalance },
    { NULL, NULL }
};

int luaopen_BankAccount(lua_State* L)
{
    luaW_register<BankAccount>(L,
        "BankAccount",
        BankAccount_table,
        BankAccount_metatable,
        BankAccount_new If your class has a default constructor you can omit this argument,
                        LuaWrapper will generate a default allocator for you.
    );
    return 1;
}

</br>


<code><pre>
#ifndef LUAEXAMPLE_HPP_
#define LUAEXAMPLE_HPP_

struct lua_State;

int luaopen_BankAccount(lua_State*);

#endif LUAEXAMPLE_HPP_

</br>


<code><pre>
alicesaccount = BankAccount.new("Alice", 100)

alicesaccount:deposit(20);
alicesaccount:deposit(30);
alicesaccount:deposit(40);

bobsaccount = BankAccount.new("Bob", 200)

bobsaccount:withdraw(10);
bobsaccount:withdraw(15);
bobsaccount:withdraw(20);

function printaccountbalance(account)
    local name = account:getOwnerName()
    local balance = account:checkBalance()
    print(string.format("%s has $%d", name, balance))
end

printaccountbalance(alicesaccount)
printaccountbalance(bobsaccount)

print(string.format("The bank has $%d", BankAccount.checkTotalMoneyInBank()))

</br>


</td>
</tr>
</table>