On Sun, Jul 17, 2011 at 2:22 AM, Steven Berry
<steven@berry.asn.au> wrote:
I have just started working on a new project using C++ and LuaJIT (and also
just started using Lua/LuaJIT) and I wanted to confirm some questions about
the best way of setting up the bindings between the two.
I'm currently not using any existing binding libraries/tools as I couldn't
find one I liked and that used the FFI. If I've missed one please let me
know.
My current approach is to run my binding generator before compilation and
generate a cpp + lua binding file.
I use clang to visit each method and output the corresponding wrapper
function.
For example, for the input:
class Test1 {
public:
void Method1(const char *text);
};
class Test2 {
public:
void Method1(Test1 *a, int b);
};
class Test3 : public Test2 {
public:
void Method2();
};
I would generate a wrapper file for the C++:
Test1 * Test1_new() {
return new Test1();
}
void Test1_delete(Test1 *__this) {
delete __this;
}
void Test1_Method1(Test1 *__this, const char *text) {
__this->Method1(text);
}
void Test2_Method1(Test2 *__this, Test1 *a, int b) {
__this->Method1(a, b);
}
void Test3_Method2(Test3 *__this) {
__this->Method2();
}
and then a Lua file:
ffi = require('ffi')
ffi.cdef[[
typedef struct { void *__this; } Test1;
typedef struct { void *__this; } Test2;
typedef struct { void *__this; } Test3;
Test1 *Test1_new();
void Test1_Method1(void *__this, const char *text);
void Test2_Method1(void *__this, void *a, int b);
void Test3_Method2(void *__this);
]]
C = ffi.C
local Test1_index = {Method1 = function(__this, text)
C.Test1_Method1(__this, text) end }
local Test1_mt = ffi.metatype("Test1", { __index = Test1_index})
Test1 = function() return Test1_mt(C.Test1_new()) end
local Test2_index = {Method1 = function(__this, a, b)
C.Test2_Method1(__this, a, b) end }
local Test2_mt = ffi.metatype("Test2", { __index = Test2_index})
Test2 = function() return Test2_mt(C.Test2_new()) end
local Test3_index = CopyTable({Method2 = function(__this)
C.Test3_Method2(__this) end }, Test2_index)
local Test3_mt = ffi.metatype("Test3", { __index = Test3_index})
Test3 = function() return Test3_mt(C.Test3_new()) end
(In my case I delete/free the objects in C++ so I don't have to worry about
gc for most of the classes)
I'm also making sure that none of the C++ classes I expose use multiple
inheritance to simplify things, and I currently use void * in the ffi cdef
so I don't have casting issues.
I can also generate non ffi bindings in a similar fashion.
I know the above works as I have it working, but I'm not sure if I've missed
something or if there is a faster/easier/better way of doing things?
Thanks,
Steven
simple = ffi.load('simple')
-- wrap into class like behavior
local mt = {}
mt.__index = mt
function
mt.id(self, ...)
return simple.Simple_id(self.super, ...)
end
function Simple(...)
local self = {super = simple.Simple_Simple(...)}
ffi.gc(self.super, simple.Simple__gc)
return setmetatable(self, mt)
end
s = Simple(6)
print(s:id())