最基本的面向对象,应该就是在调用函数的时候,能自动传入this指针。
lua用":"操作符实现了这一点,c语言要想这么做,估计也是不费吹灰之力,但c的编译器作者大概不会这么干。
所以,用面向对象的方式,来操作c的结构体,调用c的函数,其实就是借了lua的一个":"操作符而已。当然,在技术层面,还是靠metatable的支持。
太晚了,就不写了,把代码贴上来。以后考虑这个wrapper.c能否自动生成,这样,就能写个工具,把既有项目的c对象和围绕它的方法导出来。智能的oop封装。
不知道c++又怎样。
dog.h
-
struct dog{
-
int age;
-
};
-
void set_age(struct dog *dog, int age);
-
int get_age(struct dog *dog);
dog.c
-
#include<stdio.h>
-
#include<dog.h>
-
-
void set_age(struct dog *dog, int age){
-
dog->age = age;
-
}
-
int get_age(struct dog *dog){
-
return dog->age;
-
}
wrapper.c
-
#include<stdio.h>
-
#include<lua.h>
-
#include<lualib.h>
-
#include<dog.h>
-
-
-
/* 在lua里,我当然想写成dog:set_age(123)这样,也就是set_age(dog, 123)这样。
-
* 于是知道在c里怎么写了。
-
*/
-
int _set_age(lua_State *L){
-
struct dog * arg_dog = lua_touserdata(L, -2);
-
int arg_age = lua_tointeger(L, -1);
-
-
set_age(arg_dog, arg_age);
-
-
return 0;
-
}
-
-
int _get_age(lua_State *L){
-
struct dog *arg_dog = lua_touserdata(L, -1);
-
-
int age = get_age(arg_dog);
-
lua_pushinteger(L, age);
-
-
return 1;
-
}
-
-
/*prototype: userdata createDog(void)*/
-
int createDog(lua_State *L){
-
struct dog *dog = lua_newuserdata(L, sizeof(struct dog));
-
-
luaL_newmetatable(L, "metatable");
-
lua_pushstring(L, "__index");
-
lua_pushvalue(L, -2);
-
lua_settable(L, -3);
-
/**---*/
-
lua_pushstring(L, "get_age");
-
lua_pushcfunction(L, _get_age);
-
lua_settable(L, -3);
-
/*----*/
-
lua_pushstring(L, "set_age");
-
lua_pushcfunction(L, _set_age);
-
lua_settable(L, -3);
-
-
lua_setmetatable(L, -2);
-
-
return 1;
-
}
-
-
int luaopen_cmodule(lua_State *L){
-
/* lua_register(L, "set_age", _set_age);*/
-
/* lua_register(L, "get_age", _get_age);*/
-
lua_register(L, "createDog", createDog);
-
return 0;
-
}
gcc -o module.so dog.c wrapper.c -shared -llua -L../ -I../ -I./
-
wws@ubuntu:~/Downloads/lua-5.1/src/test$ lua
-
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
-
> require"cmodule"
-
> dog=createDog()
-
> dog:set_age(1)
-
> print(dog:get_age())
-
1
-
> dog:set_age(3)
-
> print(dog:get_age())
-
3
阅读(1528) | 评论(0) | 转发(0) |