1
0
mirror of https://github.com/lxsang/antd-lua-plugin synced 2025-02-22 02:32:48 +01:00

working simple ffi

This commit is contained in:
lxsang 2019-05-01 22:06:48 +02:00
parent 0ac583407d
commit f87456341f
3 changed files with 118 additions and 82 deletions

View File

@ -1,26 +1,28 @@
local ffi = require("ffi") require("cif")
local path = "/home/mrsang/Desktop/testffi/libtest.so" local path = "/Users/mrsang/Google Drive/ushare/cwp/ant-http/plugins/antd-lua-plugin/lib/ffi/example/libtest.so"
local lib = nil local lib = nil
local fn = nil local fn = nil
local rettype = nil local rettype = nil
local argtype = nil local argtype = nil
if ffi then lib = FFI.load(path)
-- now ffi exist
-- try to load the test library
lib = ffi.dlopen(path)
if lib then if lib then
-- now try to lookup for the greet function -- now try to lookup for the greet function
echo("looking for greet") echo("looking for greet")
fn = ffi.dlsym(lib,"greet") fn = FFI.lookup(lib,"greet")
if fn then if fn then
-- now the function found -- now the function found
-- tried to called it -- tried to called it
rettype = ffi.atomic_type(0) -- void rettype = FFI.atomic(FFI.type.VOID) -- void
if rettype then if rettype then
argtype = ffi.atomic_type(20) -- pointer argtype = {
FFI.atomic(FFI.type.POINTER),
FFI.atomic(FFI.type.DOUBLE),
FFI.atomic(FFI.type.SINT64),
FFI.atomic(FFI.type.SINT8)
} -- pointer
if(argtype) then if(argtype) then
-- call the function -- call the function
local r = ffi.call(rettype, {argtype}, fn, {"hello world"}) local r = FFI.call(rettype, argtype, fn, {"hello world", 0.987, -76, 65})
if r then if r then
echo("BIG SUCCESS") echo("BIG SUCCESS")
else else
@ -35,11 +37,8 @@ if ffi then
else else
echo("unable to find greet") echo("unable to find greet")
end end
ffi.dlclose(lib) FFI.unloadAll()
else else
echo("unable to load the lib") echo("unable to load the lib")
end end
else
echo("cannot find ffi")
end
echo("end the day") echo("end the day")

View File

@ -1,6 +1,6 @@
#include <stdio.h> #include <stdio.h>
void greet(const char* msg) void greet(const char* msg, float num, int sint, char c)
{ {
printf("%s\n", msg); printf("%s: '%f' '%d' '%c'\n", msg, num, sint, c);
} }

View File

@ -21,6 +21,12 @@
#include <ffi.h> #include <ffi.h>
#define MAX_FN_ARGC 32 #define MAX_FN_ARGC 32
typedef struct {
uint8_t allocated;
uint8_t is_pointer;
void* data;
} arg_pointer_t;
// define atomic type // define atomic type
typedef enum ffi_atomic_t { typedef enum ffi_atomic_t {
L_FFI_TYPE_VOID, L_FFI_TYPE_VOID,
@ -88,15 +94,12 @@ static int l_dlopen(lua_State* L)
static int l_dlclose(lua_State* L) static int l_dlclose(lua_State* L)
{ {
LOG("%s\n","Begin close");
void* handle = lua_touserdata(L,1); void* handle = lua_touserdata(L,1);
if(!handle) if(!handle)
{ {
LOG("%s\n","Cannot close that thing, handle not found");
lua_pushboolean(L,0); lua_pushboolean(L,0);
return 1; return 1;
} }
LOG("%s\n","the handle is found");
dlclose(handle); dlclose(handle);
lua_pushboolean(L,1); lua_pushboolean(L,1);
return 1; return 1;
@ -143,42 +146,84 @@ static int l_ffi_prepare(lua_State* L, ffi_type** argvtype, int idx)
return argc; return argc;
} }
void * parser_value(lua_State* L, int idx, ffi_type* ffitype) void parser_value(lua_State* L, int idx, ffi_type* ffitype, arg_pointer_t * ptr)
{ {
lua_Number * value; ptr->allocated = 1;
ptr->is_pointer = 0;
switch(ffitype->type) switch(ffitype->type)
{ {
case FFI_TYPE_VOID : return NULL;
case FFI_TYPE_POINTER: case FFI_TYPE_POINTER:
// TODO: need to fix this to universal pointer ptr->allocated = 0;
return lua_tostring(L, idx); ptr->is_pointer = 1;
ptr->data = (void*)lua_tostring(L, idx);
return;
case FFI_TYPE_UINT8: case FFI_TYPE_UINT8:
ptr->data = (void*) malloc(ffitype->size);
*((uint8_t*)ptr->data) = (uint8_t)lua_tonumber(L,idx);
return;
case FFI_TYPE_SINT8: case FFI_TYPE_SINT8:
ptr->data = (void*) malloc(ffitype->size);
*((int8_t*)ptr->data) = (int8_t)lua_tonumber(L,idx);
return;
case FFI_TYPE_UINT16: case FFI_TYPE_UINT16:
ptr->data = (void*) malloc(ffitype->size);
*((uint16_t*)ptr->data) = (uint16_t)lua_tonumber(L,idx);
return;
case FFI_TYPE_SINT16: case FFI_TYPE_SINT16:
ptr->data = (void*) malloc(ffitype->size);
*((int16_t*)ptr->data) = (int16_t)lua_tonumber(L,idx);
return;
case FFI_TYPE_UINT32: case FFI_TYPE_UINT32:
ptr->data = (void*) malloc(ffitype->size);
*((uint32_t*)ptr->data) = (uint32_t)lua_tonumber(L,idx);
return;
case FFI_TYPE_SINT32: case FFI_TYPE_SINT32:
ptr->data = (void*) malloc(ffitype->size);
*((int32_t*)ptr->data) = (int32_t)lua_tonumber(L,idx);
return;
case FFI_TYPE_UINT64: case FFI_TYPE_UINT64:
ptr->data = (void*) malloc(ffitype->size);
*((uint64_t*)ptr->data) = (uint64_t)lua_tonumber(L,idx);
return;
case FFI_TYPE_SINT64: case FFI_TYPE_SINT64:
ptr->data = (void*) malloc(ffitype->size);
*((int64_t*)ptr->data) = (int64_t)lua_tonumber(L,idx);
return;
case FFI_TYPE_LONGDOUBLE: case FFI_TYPE_LONGDOUBLE:
/*This is bug in lua*/
ptr->data = (void*) malloc(ffitype->size);
*((long double*)ptr->data) = (long double)lua_tonumber(L,idx);
return;
case FFI_TYPE_FLOAT: case FFI_TYPE_FLOAT:
case FFI_TYPE_DOUBLE: case FFI_TYPE_DOUBLE:
value = (lua_Number*) malloc(ffitype->size); ptr->data = (void*) malloc(ffitype->size);
*value = lua_tonumber(L,idx); *((float*)ptr->data) = (float)lua_tonumber(L,idx);
break; return;
case FFI_TYPE_STRUCT: /*case FFI_TYPE_STRUCT:
// not implemented yet // not implemented yet
return NULL; return NULL;
break;*/
default:
ptr->allocated = 0;
ptr->is_pointer = 0;
ptr->data = NULL;
break; break;
default: return NULL;
} }
return (void*)value;
} }
static void parser_arguments(lua_State* L, int idx, void** argv, ffi_type** argvtype) static void parser_arguments(lua_State* L, int idx, arg_pointer_t* argv, ffi_type** argvtype)
{ {
// loop through table // loop through table
lua_pushvalue(L,idx); lua_pushvalue(L,idx);
@ -189,7 +234,7 @@ static void parser_arguments(lua_State* L, int idx, void** argv, ffi_type** argv
while(lua_next(L, -2)) while(lua_next(L, -2))
{ {
// stack now contains: -1 => value; -2 key; -3 table // stack now contains: -1 => value; -2 key; -3 table
argv[i] = parser_value(L, -1, argvtype[i]); parser_value(L, -1, argvtype[i],&argv[i]);
i++; i++;
// pop the value, leaving the original key // pop the value, leaving the original key
lua_pop(L,1); lua_pop(L,1);
@ -200,29 +245,12 @@ static void parser_arguments(lua_State* L, int idx, void** argv, ffi_type** argv
lua_pop(L,1); lua_pop(L,1);
} }
static void free_arguments(void** argv, ffi_type** argvtype) static void free_arguments(arg_pointer_t* argv, int argc)
{ {
ffi_type * ffitype; for(int i = 0; i< argc; i++)
for(int i = 0; argvtype[i] != NULL; i++)
{ {
ffitype = argvtype[i]; if(argv[i].allocated)
switch (ffitype->type) free(argv[i].data);
{
case FFI_TYPE_UINT8:
case FFI_TYPE_SINT8:
case FFI_TYPE_UINT16:
case FFI_TYPE_SINT16:
case FFI_TYPE_UINT32:
case FFI_TYPE_SINT32:
case FFI_TYPE_UINT64:
case FFI_TYPE_SINT64:
case FFI_TYPE_LONGDOUBLE:
case FFI_TYPE_FLOAT:
case FFI_TYPE_DOUBLE:
if(argv[i]) free(argv[i]);
break;
default: break;
}
} }
} }
@ -230,36 +258,45 @@ static void free_arguments(void** argv, ffi_type** argvtype)
static int l_ffi_call(lua_State* L) static int l_ffi_call(lua_State* L)
{ {
ffi_type * argvtype[MAX_FN_ARGC]; ffi_type * argvtype[MAX_FN_ARGC];
void* argv[MAX_FN_ARGC];
ffi_type * rettype = lua_touserdata(L,1); ffi_type * rettype = lua_touserdata(L,1);
int argc = l_ffi_prepare(L, argvtype, 2); int argc = l_ffi_prepare(L, argvtype, 2);
printf("Argument count %d\n", argc); arg_pointer_t* args;
printf("ret type: %d\n", rettype->type);
void* argv[MAX_FN_ARGC];
ffi_arg ret; ffi_arg ret;
ffi_cif cif; ffi_cif cif;
if(ffi_prep_cif(&cif,FFI_DEFAULT_ABI,argc,rettype,argvtype) == FFI_OK) if(ffi_prep_cif(&cif,FFI_DEFAULT_ABI,argc,rettype,argvtype) == FFI_OK)
{ {
void(* fn)(const char*) = lua_touserdata(L,3); void * fn = lua_touserdata(L,3);
if(!fn) if(!fn)
{ {
LOG("%s\n", "function not found"); LOG("%s\n", "function not found");
lua_pushboolean(L,0); lua_pushboolean(L,0);
return 1; return 1;
} }
if(lua_rawlen(L,4) != argc)
{
LOG("%s\n", "Argument count does not not match");
lua_pushboolean(L,0);
return 1;
}
// the arguments of the function is at 4th position on the stack // the arguments of the function is at 4th position on the stack
// we need to loop through this table and check if argument type // we need to loop through this table and check if argument type
// is correct to the definition in argvtype // is correct to the definition in argvtype
//argv = (void**)malloc(sizeof(void*)*argc); args = (arg_pointer_t*)malloc(sizeof(arg_pointer_t)*(argc+1));
//ret = (void*)malloc(rettype->size); //ret = (void*)malloc(rettype->size);
// now parser the argument // now parser the argument
parser_arguments(L,4,argv,argvtype); parser_arguments(L,4,args,argvtype);
// test
char* tmp = (char*)argv[0]; for(int i = 0; i< argc; i++)
argv[0] = &tmp; {
if(args[i].is_pointer && args[i].data)
argv[i] = &(args[i].data);
else
argv[i] = args[i].data;
}
ffi_call(&cif,fn, &ret, argv); ffi_call(&cif,fn, &ret, argv);
free_arguments(argv, argvtype); free_arguments(args, argc);
//if(argv) free(argv); if(args) free(args);
//if(ret) free(ret);
lua_pushboolean(L,1); lua_pushboolean(L,1);
return 1; return 1;
} }
@ -321,7 +358,7 @@ static const struct luaL_Reg _lib [] = {
{"dlsym",l_dlsym}, {"dlsym",l_dlsym},
{"dlclose",l_dlclose}, {"dlclose",l_dlclose},
{"call",l_ffi_call}, {"call",l_ffi_call},
{"atomic_type", l_ffi_atomic_type}, {"atomic", l_ffi_atomic_type},
{"struct", l_ffi_struct }, {"struct", l_ffi_struct },
{NULL,NULL} {NULL,NULL}
}; };