Sunday, February 26, 2017

boost mpl if demonstration

Consider the following code adapted from Polukhin:

#include <boost/mpl/if.hpp>
#include <boost/type_traits/has_plus_assign.hpp>
#include <boost/type_traits/has_plus.hpp>
#include <boost/type_traits/has_post_increment.hpp>
#include <boost/type_traits/has_pre_increment.hpp>
#include <cstdio>
namespace detail {
struct pre_inc_functor {
template <class T>
void operator()(T& value) const {
printf("%s\n", __FUNCTION__);
++value;
}
};
struct post_inc_functor {
template <class T>
void operator()(T& value) const {
printf("%s\n", __FUNCTION__);
value++;
}
};
struct plus_assignable_functor {
template <class T>
void operator()(T& value) const {
printf("%s\n", __FUNCTION__);
value += T(1);
}
};
struct plus_functor {
template <class T>
void operator()(T& value) const {
printf("%s\n", __FUNCTION__);
value = value + T(1);
}
};
}
template <class T>
void inc(T& value) {
typedef detail::plus_functor step_0_t;
typedef typename boost::mpl::if_<
boost::has_plus_assign<T>,
detail::plus_assignable_functor,
step_0_t
>::type step_1_t;
typedef typename boost::mpl::if_<
boost::has_post_increment<T>,
detail::post_inc_functor,
step_1_t
>::type step_2_t;
typedef typename boost::mpl::if_<
boost::has_pre_increment<T>,
detail::pre_inc_functor,
step_2_t
>::type step_3_t;
step_3_t() // default constructing functor
(value); // calling operator() of a functor
}
class cls
{
public:
cls(int val): m_int(val) {}
cls operator+=(cls const& rhs)
{
printf("%s\n", __FUNCTION__);
m_int += rhs.m_int;
return *this;
}
int get()
{
return m_int;
}
private:
int m_int;
};
class post
{
public:
post(int val): m_int(val) {}
post operator++(int)
{
printf("%s\n", __FUNCTION__);
post tmp(m_int);
++m_int;
return tmp;
}
int get()
{
return m_int;
}
private:
int m_int;
};
int main()
{
int x = 5;
inc(x);
printf("x = %d\n", x);
cls y(89);
inc(y);
printf("y = %d\n", y.get());
post z(140);
inc(z);
printf("z = %d\n", z.get());
post alpha = z++;
printf("alpha = %d\n", alpha.get());
printf("z = %d\n", z.get());
return 0;
}
view raw b.cpp hosted with ❤ by GitHub
When run:

detail::pre_inc_functor::operator ()
x = 6
detail::plus_assignable_functor::operator ()
cls::operator +=
y = 90
detail::post_inc_functor::operator ()
post::operator ++
z = 141
post::operator ++
alpha = 141
z = 142

Saturday, February 25, 2017

boost mpl manipulating a vector

Consider the following code copied from Polukhin:

#include <iostream>
#include <boost/mpl/size.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/static_assert.hpp>
#include <boost/mpl/if.hpp>
#include <boost/type_traits/make_unsigned.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/at.hpp>
// Make unsigned
struct unsigne; // No typo: 'unsigned' is a keyword, we cannot use it.
// Make constant
struct constant;
// Otherwise we do not change type
struct no_change;
template <class Types, class Modifiers>
struct do_modifications
{
BOOST_STATIC_ASSERT((boost::is_same<
typename boost::mpl::size<Types>::type,
typename boost::mpl::size<Modifiers>::type
>::value));
typedef boost::mpl::if_<
boost::is_same<boost::mpl::_2, unsigne>,
boost::make_unsigned<boost::mpl::_1>,
boost::mpl::if_<
boost::is_same<boost::mpl::_2, constant>,
boost::add_const<boost::mpl::_1>,
boost::mpl::_1
>
> binary_operator_t;
typedef typename boost::mpl::transform<
Types,
Modifiers,
binary_operator_t
>::type type;
};
typedef boost::mpl::vector<unsigne, no_change, constant, unsigne> modifiers;
typedef boost::mpl::vector<int, char, short, long> types;
typedef do_modifications<types, modifiers>::type result_type;
BOOST_STATIC_ASSERT((boost::is_same<
boost::mpl::at_c<result_type, 0>::type,
unsigned int
>::value));
BOOST_STATIC_ASSERT((boost::is_same<
boost::mpl::at_c<result_type, 1>::type,
char
>::value));
BOOST_STATIC_ASSERT((boost::is_same<
boost::mpl::at_c<result_type, 2>::type,
const short
>::value));
BOOST_STATIC_ASSERT((boost::is_same<
boost::mpl::at_c<result_type, 3>::type,
unsigned long
>::value));
int main(int argc, char *argv[])
{
auto x = 78;
std::cout << "Hello World! " << x << std::endl;
return 0;
}
view raw main.cpp hosted with ❤ by GitHub

When run, this code simply prints "Hello World! 78"

Thursday, February 23, 2017

Luabind tostring demonstration

Consider the following code:

#include <string>
#include <iostream>
#include <luabind/luabind.hpp>
#include <luabind/operator.hpp>
class testclass
{
public:
testclass(int val) : m_int(val) {}
friend std::ostream& operator<<(std::ostream& os, testclass const& tc);
private:
int m_int;
};
std::ostream& operator<<(std::ostream& os, testclass const& tc)
{
os << tc.m_int;
return os;
}
extern "C" int init(lua_State* L)
{
using namespace luabind;
open(L);
module(L)
[
class_<testclass>("testclass")
.def(constructor<int>())
.def(tostring(self))
];
return 0;
}
view raw tostring.cpp hosted with ❤ by GitHub
When run:

kuyu@ub16:~/dkuyu/Dropbox/practice/lua/luabind/tostring$ cat test.lua
package.loadlib('./testclass.so', 'init')()
a = testclass(101)
print(tostring(a))
kuyu@ub16:~/dkuyu/Dropbox/practice/lua/luabind/tostring$ cat commands.bash
#!/bin/bash
g++ testclass.cpp -I/usr/include/lua5.2/ -c -fPIC
g++ -shared -Wl,--whole-archive -o testclass.so testclass.o -lluabind -Wl,--no-whole-archive
lua test.lua
kuyu@ub16:~/dkuyu/Dropbox/practice/lua/luabind/tostring$ ./commands.bash
101
kuyu@ub16:~/dkuyu/Dropbox/practice/lua/luabind/tostring$

Luabind operator other() demonstration

Consider the following code:

#include <string>
#include <iostream>
#include <luabind/luabind.hpp>
#include <luabind/operator.hpp>
class testclass
{
public:
testclass(int val) : m_int(val) {}
void print()
{
std::cout << m_int << std::endl;
}
testclass operator+(testclass const& rhs)
{
testclass tmp(m_int + rhs.m_int);
return tmp;
}
private:
int m_int;
};
extern "C" int init(lua_State* L)
{
using namespace luabind;
open(L);
module(L)
[
class_<testclass>("testclass")
.def(constructor<int>())
.def("print", &testclass::print)
.def(self + other<testclass>())
];
return 0;
}

When run:

kuyu@ub16:~/dkuyu/Dropbox/practice/lua/luabind/operator_other$ cat test.lua
package.loadlib('./testclass.so', 'init')()
a = testclass(5)
b = testclass(9)
c = a + b
a:print()
b:print()
c:print()
kuyu@ub16:~/dkuyu/Dropbox/practice/lua/luabind/operator_other$ cat commands.bash
#!/bin/bash
g++ testclass.cpp -I/usr/include/lua5.2/ -c -fPIC
g++ -shared -Wl,--whole-archive -o testclass.so testclass.o -lluabind -Wl,--no-whole-archive
lua test.lua
kuyu@ub16:~/dkuyu/Dropbox/practice/lua/luabind/operator_other$ ./commands.bash
5
9
14
kuyu@ub16:~/dkuyu/Dropbox/practice/lua/luabind/operator_other$

Luabind operator demonstration

Consider the following code:

#include <string>
#include <iostream>
#include <luabind/luabind.hpp>
#include <luabind/operator.hpp>
class testclass
{
public:
testclass(int val) : m_int(val) {}
void print()
{
std::cout << m_int << std::endl;
}
testclass operator+(int rhs)
{
testclass tmp(m_int + rhs);
return tmp;
}
private:
int m_int;
};
extern "C" int init(lua_State* L)
{
using namespace luabind;
open(L);
module(L)
[
class_<testclass>("testclass")
.def(constructor<int>())
.def("print", &testclass::print)
.def(self + int())
];
return 0;
}
view raw operator.cpp hosted with ❤ by GitHub

When run:

kuyu@ub16:~/dkuyu/Dropbox/practice/lua/luabind/operator$ cat test.lua
package.loadlib('./testclass.so', 'init')()
a = testclass(5)
a:print()
c = a + 6
c:print()
kuyu@ub16:~/dkuyu/Dropbox/practice/lua/luabind/operator$ cat commands.bash 
#!/bin/bash
g++ testclass.cpp -I/usr/include/lua5.2/ -c -fPIC
g++ -shared -Wl,--whole-archive -o testclass.so testclass.o -lluabind -Wl,--no-whole-archive
lua test.lua
kuyu@ub16:~/dkuyu/Dropbox/practice/lua/luabind/operator$ ./commands.bash 
5
11
kuyu@ub16:~/dkuyu/Dropbox/practice/lua/luabind/operator$ 

Luabind: enums demonstration

Consider the following code:

#include <string>
#include <iostream>
#include <luabind/luabind.hpp>
struct A
{
A() {}
enum
{
first = 1
, second = 2
, thirds = 3
};
};
extern "C" int init(lua_State* L)
{
using namespace luabind;
open(L);
module(L)
[
class_<A>("A")
.def(constructor<>())
.enum_("constants")
[
value("first", 1),
value("second", 2),
value("third", 3)
]
];
return 0;
}
view raw enums.cpp hosted with ❤ by GitHub
When run:

kuyu@ub16:~/dkuyu/Dropbox/practice/lua/luabind/enums$ cat test.lua 
package.loadlib('./testclass.so', 'init')()
print(A.first)
print(A.second)
print(A.third)
kuyu@ub16:~/dkuyu/Dropbox/practice/lua/luabind/enums$ cat ./commands.bash 
#!/bin/bash
g++ testclass.cpp -I/usr/include/lua5.2/ -c -fPIC
g++ -shared -Wl,--whole-archive -o testclass.so testclass.o -lluabind -Wl,--no-whole-archive
lua test.lua
kuyu@ub16:~/dkuyu/Dropbox/practice/lua/luabind/enums$ ./commands.bash 
1
2
3
kuyu@ub16:~/dkuyu/Dropbox/practice/lua/luabind/enums$ 

You actually don't have to define the enum in the C++ struct A. Try removing it and the test.lua will still work.

Saturday, February 18, 2017

boost mpl vector demonstration

Consider the following code copied from Polukhin's book:

#include <boost/mpl/aux_/na.hpp>
// boost::mpl::na == n.a. == not available
template <
class T0 = boost::mpl::na,
class T1 = boost::mpl::na,
class T2 = boost::mpl::na,
class T3 = boost::mpl::na,
class T4 = boost::mpl::na,
class T5 = boost::mpl::na,
class T6 = boost::mpl::na,
class T7 = boost::mpl::na,
class T8 = boost::mpl::na,
class T9 = boost::mpl::na
>
struct variant;
#include <boost/mpl/vector.hpp>
template <
class T0
, class T1
, class T2
, class T3
, class T4
, class T5
, class T6
, class T7
, class T8
, class T9
>
struct variant {
typedef boost::mpl::vector<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> types;
};
#include <string>
struct declared{ unsigned char data[4096]; };
struct non_defined;
typedef variant<
volatile int,
const int,
const long,
declared,
non_defined,
std::string
>::types types;
#include <boost/static_assert.hpp>
#include <boost/mpl/empty.hpp>
BOOST_STATIC_ASSERT((!boost::mpl::empty<types>::value));
#include <boost/mpl/at.hpp>
#include <boost/type_traits/is_same.hpp>
BOOST_STATIC_ASSERT((boost::is_same<
non_defined
, boost::mpl::at_c<types, 4>::type>::value));
#include <boost/mpl/back.hpp>
BOOST_STATIC_ASSERT((boost::is_same<
std::string
, boost::mpl::back<types>::type>::value));
#include <boost/mpl/transform.hpp>
#include <boost/type_traits/remove_cv.hpp>
typedef boost::mpl::transform<
types,
boost::remove_cv<boost::mpl::_1>
>::type noncv_types;
#include <boost/mpl/unique.hpp>
typedef boost::mpl::unique<
noncv_types,
boost::is_same<boost::mpl::_1, boost::mpl::_2>
>::type unique_types;
#include <boost/mpl/size.hpp>
BOOST_STATIC_ASSERT((boost::mpl::size<unique_types>::value == 5));
// Without this we'll get an error:
// use of undefined type 'non_defined'
struct non_defined{};
#include <boost/mpl/sizeof.hpp>
typedef boost::mpl::transform<
unique_types,
boost::mpl::sizeof_<boost::mpl::_1>
>::type sizes_types;
#include <boost/mpl/max_element.hpp>
typedef boost::mpl::max_element<sizes_types>::type max_size_type;
BOOST_STATIC_ASSERT(max_size_type::type::value == sizeof(declared));
int main()
{
return 0;
}
view raw d.cpp hosted with ❤ by GitHub

When run, this code prints nothing. All checking is done at compile time.

boost enable_if_c example

Consider the following code adapted from Polukhin's book:

#include <iostream>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/is_float.hpp>
// Generic implementation
template <class T, class enable = void>
class data_processor {
public:
double process(const T& v1, const T& v2, const T& v3)
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
};
// Integral types optimized version
template <class T>
class data_processor<T, typename boost::enable_if_c<boost::is_integral<T>::value>::type>
{
public:
double process(const T& v1, const T& v2, const T& v3)
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
};
// SSE optimized version for float types
template <class T>
class data_processor<T, typename boost::enable_if_c<boost::is_float<T>::value>::type>
{
public:
double process(const T& v1, const T& v2, const T& v3)
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
};
template <class T>
double example_func(T v1, T v2, T v3) {
data_processor<T> proc;
return proc.process(v1, v2, v3);
}
int main () {
// Integral types optimized version will be called
example_func(1, 2, 3);
short s = 0;
example_func(s, s, s);
// Real types version will be called
example_func(1.0, 2.0, 3.0);
example_func(1.0f, 2.0f, 3.0f);
// Generic version will be called
example_func("Hello", "word", "processing");
return 0;
}
view raw c.cpp hosted with ❤ by GitHub

When run:

kuyu@ub16:~/dkuyu/Dropbox/practice/cpp/boost/polukhin/ch04/enable_if_c$ g++ -I~/dkuyu/bin/boost_1_60_0 c.cpp && ./a.out
double data_processor<T, typename boost::enable_if_c<boost::is_integral<T>::value>::type>::process(const T&, const T&, const T&) [with T = int; typename boost::enable_if_c<boost::is_integral<T>::value>::type = void]
double data_processor<T, typename boost::enable_if_c<boost::is_integral<T>::value>::type>::process(const T&, const T&, const T&) [with T = short int; typename boost::enable_if_c<boost::is_integral<T>::value>::type = void]
double data_processor<T, typename boost::enable_if_c<boost::is_float<T>::value>::type>::process(const T&, const T&, const T&) [with T = double; typename boost::enable_if_c<boost::is_float<T>::value>::type = void]
double data_processor<T, typename boost::enable_if_c<boost::is_float<T>::value>::type>::process(const T&, const T&, const T&) [with T = float; typename boost::enable_if_c<boost::is_float<T>::value>::type = void]
double data_processor<T, enable>::process(const T&, const T&, const T&) [with T = const char*; enable = void]

Thursday, February 9, 2017

Luabind: properties demonstration

Consider the following code:

#include <string>
#include <iostream>
#include <luabind/luabind.hpp>
struct A
{
A(int val): a(val), b(5) {}
int a;
int b;
};
extern "C" int init(lua_State* L)
{
using namespace luabind;
open(L);
module(L)
[
class_<A>("A")
.def(constructor<int>())
.def_readwrite("a", &A::a)
.def_readonly("b", &A::b)
];
return 0;
}
view raw properties.cpp hosted with ❤ by GitHub
When run:

kuyu@ub16:~/dkuyu/Dropbox/practice/lua/luabind/properties$ cat commands.bash 
#!/bin/bash
g++ testclass.cpp -I/usr/include/lua5.2/ -c -fPIC
g++ -shared -Wl,--whole-archive -o testclass.so testclass.o -lluabind -Wl,--no-whole-archive
lua test.lua
kuyu@ub16:~/dkuyu/Dropbox/practice/lua/luabind/properties$ ./commands.bash 
7
89
5
lua: property 'b' is read only
stack traceback:
[C]: in function '__newindex'
test.lua:7: in main chunk
[C]: in ?
kuyu@ub16:~/dkuyu/Dropbox/practice/lua/luabind/properties$ 

Luabind: Binding an overloaded class function

Consider the following code:

#include <string>
#include <iostream>
#include <luabind/luabind.hpp>
class overloaded_function
{
public:
overloaded_function() {}
void print_string() { std::cout << __FUNCTION__ << std::endl; }
void print_string(int x) { std::cout << __FUNCTION__ << ": " << x << std::endl; }
};
extern "C" int init(lua_State* L)
{
using namespace luabind;
open(L);
module(L)
[
class_<overloaded_function>("overloaded_function")
.def(constructor<>())
.def("print_string", (void(overloaded_function::*)(int))&overloaded_function::print_string)
];
return 0;
}

When run:

kuyu@ub16:~/dkuyu/Dropbox/practice/lua/luabind/overloaded_function$ cat test.lua 
package.loadlib('./overloaded_function.so', 'init')()
a = overloaded_function()
a:print_string(6)
kuyu@ub16:~/dkuyu/Dropbox/practice/lua/luabind/overloaded_function$ cat commands.bash 
#!/bin/bash
g++ overloaded_function.cpp -I/usr/include/lua5.2/ -c -fPIC
g++ -shared -Wl,--whole-archive -o overloaded_function.so overloaded_function.o -lluabind -Wl,--no-whole-archive
lua test.lua
kuyu@ub16:~/dkuyu/Dropbox/practice/lua/luabind/overloaded_function$ ./commands.bash 
print_string: 6

Wednesday, February 8, 2017

Consider the following code which registers a free function (plus()) as a member function of class A:

#include <string>
#include <iostream>
#include <luabind/luabind.hpp>
struct A
{
A(int val): a(val) {}
int a;
};
int plus(A* o, int v)
{
return o->a + v;
}
extern "C" int init(lua_State* L)
{
using namespace luabind;
open(L);
module(L)
[
class_<A>("A")
.def(constructor<int>())
.def("plus", &plus)
];
return 0;
}
When run:

kuyu@ub16:~/dkuyu/Dropbox/practice/lua/luabind/register_free$ cat test.lua
package.loadlib('./register_free.so', 'init')()
x = A(3)
print(x:plus(5))
kuyu@ub16:~/dkuyu/Dropbox/practice/lua/luabind/register_free$ cat commands.bash
#!/bin/bash
g++ register_free.cpp -I/usr/include/lua5.2/ -c -fPIC
g++ -shared -Wl,--whole-archive -o register_free.so register_free.o -lluabind -Wl,--no-whole-archive
lua test.lua
kuyu@ub16:~/dkuyu/Dropbox/practice/lua/luabind/register_free$ ./commands.bash
8
kuyu@ub16:~/dkuyu/Dropbox/practice/lua/luabind/register_free$

Luabind class demonstration

Consider this code that exposes a C++ class to Lua:

#include <string>
#include <iostream>
#include <luabind/luabind.hpp>
class testclass
{
public:
testclass(const std::string& s): m_string(s) {}
void print_string() { std::cout << m_string << "\n"; }
private:
std::string m_string;
};
extern "C" int init(lua_State* L)
{
using namespace luabind;
open(L);
module(L)
[
class_<testclass>("testclass")
.def(constructor<const std::string&>())
.def("print_string", &testclass::print_string)
];
return 0;
}
view raw testclass.cpp hosted with ❤ by GitHub
When run:

kuyu@ub16:~/dkuyu/Dropbox/practice/lua/luabind/testclass$ cat test.lua 
package.loadlib('./testclass.so', 'init')()
a = testclass('a string')
a:print_string()
kuyu@ub16:~/dkuyu/Dropbox/practice/lua/luabind/testclass$ cat commands.bash 
#!/bin/bash
g++ testclass.cpp -I/usr/include/lua5.2/ -c -fPIC
g++ -shared -Wl,--whole-archive -o testclass.so testclass.o -lluabind -Wl,--no-whole-archive
lua test.lua
kuyu@ub16:~/dkuyu/Dropbox/practice/lua/luabind/testclass$ ./commands.bash 
a string

Saturday, February 4, 2017

Implementing a type trait

I copied/adapted this code from Polukhin's Boost book:

#include <vector>
#include <boost/type_traits/integral_constant.hpp>
#include <cstdio>
template <class T>
struct is_stdvector: boost::false_type {};
template <class T, class Allocator>
struct is_stdvector<std::vector<T, Allocator> >: boost::true_type
{};
int main()
{
printf("int=%s\n", is_stdvector<int>::value ? "true" : "false");
printf("vector<int>=%s\n", is_stdvector<std::vector<int>>::value ? "true" : "false");
printf("vector<char*>=%s\n", is_stdvector<std::vector<char*>>::value ? "true" : "false");
return 0;
}
When run:

kuyu@ub16:~/dkuyu/Dropbox/practice/cpp/polukhin/ch04/implement_type_trait$ g++ -std=c++11 -I/home/kuyu/dkuyu/bin/boost_1_60_0 1.cpp && ./a.out
int=false
vector<int>=true
vector<char*>=true



Friday, February 3, 2017

How to make a Windows folder always available in Ubuntu in Oracle Virtualbox

First share your Windows folder to your Ubuntu virtual machine in Oracle Virtualbox:



In your Ubuntu machine, add a similar line to your /etc/fstab file:

dkuyu   /home/kuyu/dkuyu    vboxsf  uid=kuyu,gid=kuyu,rw,dmode=700,fmode=700,_netdev      0 0

(Be sure to create the Linux folder afterwards. You can do this via mkdir command. In this example, make sure that /home/kuyu/dkuyu exists. If not, create it.)

Reboot your Ubuntu virtual machine.

After reboot, the Windows folder should be available in the Ubuntu folder /home/kuyu/dkuyu (for this example).

Luabind for sin math function

First we register the cmath sin() function as a function named sin() in Lua:

#include <iostream>
#include <luabind/luabind.hpp>
#include <cmath>
extern "C" int init(lua_State* L)
{
using namespace luabind;
open(L);
module(L)
[
def("sin", (float(*)(float)) &std::sin)
];
return 0;
}
view raw sin.cpp hosted with ❤ by GitHub
We write a simple script to test the Lua sin() function:

kuyu@castor-ub:~/dkuyu/Dropbox/practice/lua/luabind/sin$ cat test.lua 
package.loadlib('./c.so', 'init')()
print(sin(1.57))

We compile and test it as follows:

kuyu@castor-ub:~/dkuyu/Dropbox/practice/lua/luabind/sin$ cat commands.bash 
#!/bin/bash
g++ c.cpp -I/usr/include/lua5.2/ -c -fPIC
g++ -shared -Wl,--whole-archive -o c.so c.o -lluabind -Wl,--no-whole-archive
lua test.lua
kuyu@castor-ub:~/dkuyu/Dropbox/practice/lua/luabind/sin$ ./commands.bash 
0.99999970197678

(1.57 is very close to pi/2 and the sin of pi/2 is 1.)

Thursday, February 2, 2017

Making luabind work in ubuntu

To be able to run Luabind in Ubuntu, you need to install libluabind-dev and lua:
kuyu@ub16:~/dkuyu/Dropbox/practice/lua/luabind/hellobind$ sudo apt-get install libluabind-dev
kuyu@ub16:~/dkuyu/Dropbox/practice/lua/luabind/hellobind$ sudo apt-get install lua

Consider this hellobind.cpp code:
#include <iostream>
#include <luabind/luabind.hpp>
void greet()
{
std::cout << "hello world!\n";
}
extern "C" int init(lua_State* L)
{
using namespace luabind;
open(L);
module(L)
[
def("greet", &greet)
];
return 0;
}
view raw hellobind.cpp hosted with ❤ by GitHub

Then consider this test.lua code:

kuyu@castor-ub:~/dkuyu/Dropbox/practice/lua/luabind/hellobind$ cat test.lua
package.loadlib('./hellobind.so', 'init')()
greet()

To run the test.lua code:

kuyu@castor-ub:~/dkuyu/Dropbox/practice/lua/luabind/hellobind$ cat commands.bash 
#!/bin/bash
g++ hellobind.cpp -I/usr/include/lua5.2/ -c -fPIC
g++ -shared -Wl,--whole-archive -o hellobind.so hellobind.o -lluabind -Wl,--no-whole-archive
lua test.lua
kuyu@castor-ub:~/dkuyu/Dropbox/practice/lua/luabind/hellobind$ ./commands.bash 
hello world!

Sometimes, loading the C++ library in Lua can be problematic. To see what the problems are when loading the library, you can execute this lua file (execute "lua test1.lua"):

kuyu@castor-ub:~/dkuyu/Dropbox/practice/lua/luabind/hellobind$ cat test1.lua
local initfunction, errormessage = package.loadlib('/home/kuyu/dkuyu/Dropbox/practice/lua/luabind/hellobind.so','init')
if errormessage then
    print('Error loading hello_world:', errormessage)
end