Creating a struct of callbacks in LuaJIT FFI - c

So first I load in a DLL I need
local ffi = require("ffi")
local theDLL = ffi.load("thisDLL")
in the ffi cdef I have this struct
ffi.cdef [[
typedef struct {
/*
* begin_proj callback
*/
bool (__cdecl *begin_proj)(char *proj);
/*
* save_proj_state
*/
bool (__cdecl *save_proj_state)(unsigned char **buffer, int *len);
} StructCallbacks;
I also have this function in the cdef
__declspec(dllexport) int __cdecl start_session(StructCallbacks *cb);
Now I would like to call this function
print(theDLL.start_session(myCallbacks))
the question is how can I pass the structs the function needs (how do I make myCallbacks a struct of callbacks to Lua functions)?

Just create the struct and assign the fields to Lua functions, as you would with any other value.
local callbacks = ffi.new("StructCallbacks")
callbacks.begin_proj = function(proj) return false end
callbacks.save_proj_state = function(buffer, len) return true end
See the FFI callback docs for more in-depth information on callbacks.

Related

how to call flutter function in C [duplicate]

Hello I am using dart:ffi to build an interface with my native c/c++ library.
and I needed a way to get a callback from c to dart as an example in sqlite:
int sqlite3_exec(
sqlite3*, /* An open database */
const char *sql, /* SQL to be evaluated */
int (*callback)(void*,int,char**,char**), /* Callback function */
void *, /* 1st argument to callback */
char **errmsg /* Error msg written here */
);
the third parameter in sqlite3_exec is function pointer to a callback.
so if I called this function in dart using ffi I need to pass a function pointer: and in dart:ffi Pointer class there is a function named fromFunction witch accepts a dart static function and an exceptionalReturn; but just by calling this function to get the function pointer of a dart managed function: a (sigterm) is raised and the dart code no long work in the process.
So My Question: Is there any way to get a native callback in dart, as in Python, c#, ..
Extra:
Is there any way to include dartino in a flutter project, since this ForeignDartFunction covers what I need.
I got an example to work. Hopefully you can adapt this to your case.
Example C function
EXTERNC int32_t foo(
int32_t bar,
int32_t (*callback)(void*, int32_t)
) {
return callback(nullptr, bar);
}
Dart code
First the typedefs. We need two for the native function foo and one for the Dart callback.
typedef example_foo = Int32 Function(
Int32 bar, Pointer<NativeFunction<example_callback>>);
typedef ExampleFoo = int Function(
int bar, Pointer<NativeFunction<example_callback>>);
typedef example_callback = Int32 Function(Pointer<Void>, Int32);
and the code for the callback
static int callback(Pointer<Void> ptr, int i) {
print('in callback i=$i');
return i + 1;
}
and the lookup
ExampleFoo nativeFoo =
nativeLib.lookup<NativeFunction<example_foo>>('foo').asFunction();
and, finally, use it like this:
int foo(int i) {
return nativeFoo(
i,
Pointer.fromFunction<example_callback>(callback, except),
);
}
as expected, foo(123) prints flutter: in callback i=123 and returns 124

Calling C nested function pointer from Lua

I have the following C struct, that contains function pointer:
struct db {
struct db_impl *impl;
void (*test)(struct db *self); // How to invoke it from Lua??
};
void (*db_test)(void); // this I can invoke from Lua
struct db * get_db() {
// create and init db
struct db * db = init ...
db->test = &db_real_impl; // db_real_impl is some C function
return db;
}
So the test function pointer after initialization points to some function.
Now I need to call that function from Lua using FFI library, but it fails with error: 'void' is not callable.
local db = ffi.C.get_db()
db.test(db) -- fails to invoke
-- Error message: 'void' is not callable
ffi.C.db_test() -- this works fine
In C the code would be:
struct db *db = get_db();
db->test(db);
In Lua I'm able to invoke free function pointers easily, but can't invoke function pointer from struct. How to invoke it from Lua?
A solution seems to be pointed out in :
http://lua-users.org/lists/lua-l/2015-07/msg00172.html
ffi.cdef[[
typedef void (*test)(struct db *);
]]
local db = get_db()
local call = ffi.cast("test", db.test)
call(db)

object oriented approach in c program

I don't have much experience in Object oriented programming.I am trying to create an object in c which will have its own methods.
I have declared structure which have pointers to function. All instance of this variable are going to point same function. But currently I need to initialize every instance of variable as in main (Line 1 and Line 2). So is there any method that will initialize its default value when I declare it?
#include <stdio.h>
#include <stdlib.h>
typedef struct serialStr Serial;
struct serialStr
{
void(*init)(Serial*);
void(*open)();
void(*close)();
};
void open()
{
printf("Open Port Success\n");
return;
}
void close()
{
printf("Close port Success\n");
return;
}
void init(Serial* ptr)
{
ptr->open = open;
ptr->close = close;
}
int main()
{
Serial serial,serial_2;
serial.init = init;
serial.init(&serial); // Line1
serial_2.init = init;
serial_2.init(&serial_2); // Line2
serial.open();
//rest of code
serial.close();
serial_2.open();
serial_2.close();
return 0;
}
In C, the standard way would be to declare an initializer macro:
#define SERIAL_INITIALIZER { .init = init, .open = open, /* and others */ }
Serial serial = SERIAL_INITIALIZER;
In most cases in C there is simply no need for dynamic intialization of variables. You only need it for malloced objects.
C++ add some automatization by calling constructor/destructor. In pure C is no way to do so. You should do all steps manually: create and initialize object (call constructor-like function for structure), call functions by pointers from the structure instance, call destructor (it should destroy the instance and free related resources).
If is no polymorphism in your task then use simple way - without pointers to functions, but each function (method) should take pointer to the object.
Common case example:
struct MyStruct
{
// data
};
struct MyStruct* createMyStruct(/* maybe some input */)
{
// create, init and return the structure instance
}
void destoyMyStruct(struct MyStruct* obj)
{
// free resources and delete the instance
}
void doSomeAction(struct MyStruct* obj /* , some other data */)
{
// ...
}
int main()
{
struct MyStruct* object = createMyStruct();
doSomeAction(object);
destoyMyStruct(object);
return 0;
}
Edit 1: macro is only for very simple cases and error-prone way.
Typically, you would do this through "opaque type". Meaning that you declare an object of incomplete type in your header:
typedef struct Serial Serial;
And then in the C file, you place the actual struct definition. This will hide the contents of the struct to the caller (private encapsulation). From your constructor, you could then set up private member functions:
struct Serial
{
void(*init)(void);
void(*open)(void);
void(*close)(void);
};
// private member functions:
static void open (void);
...
// constructor:
Serial* SerialCreate (void)
{
Serial* s = malloc(sizeof (*s));
...
s->open = open;
return s;
}
This means that if you wish to inherit the class, you will only need to change the constructor.
Though of course, if you wish to implement true polymorphism, you don't want to change any code. You could solve this by passing the init function as parameter to the constructor.
header file:
typedef void init_func_t (void);
c file:
// constructor:
Serial* SerialCreate (init_func_t* init)
{
Serial* s = malloc(sizeof (*s));
...
init();
return s;
}
And then from the init function in the inherited class, set all private member functions.

Wrapping function pointer

I am trying to wrap a library for porting purpose. The library exposes a function say -
fooLib(int , char , function pointer A);
signature of the function pointer A is
void handler(DataFormat);
where DataFormat is a struct
I don't want my wrapper to expose this library's callback function. I want to create a different function that should be used by the consumers of my wrapper, say
int handlerNew(NewDataFormat);
where NewDataFormat is my struct
The question now is how can I link these two functions? Whenever the library calls handler I want it to call my callback handlerNew after filling up the NewDataFormat struct from the DataFormat.
As long as you don't need thread safety, this is not hard. You just have to provide a private (static) handler with the library's interface that transforms the library data struct into your wrapped version, then calls your callback with that as an argument. Your interface will look like:
// wrapped_foo_lib.h
typedef struct { ... } NewDataFormat;
typedef void (*WRAPPED_CALLBACK)(NewDataFormat);
void wrappedFooLibCall(int x, char c, WRAPPED_CALLBACK cb);
Your implementation, which the client never gets to see is:
// wrapped_foo_lib.c
// This static var makes this module _not_ thread safe.
static WRAPPED_CALLBACK wrapped_callback;
static void private_handler(DataFormat data) {
NewDataFormat new_data = ...; // extract new_data from data
wrapped_callback(new_data);
}
void wrappedFooLibCall(int x, char c, WRAPPED_CALLBACK cb) {
wrapped_callback = cb;
foo_lib(x, c, private_handler);
}
The non-thread safety is why every API callback should include a void * that you get to define, which is passed on to the callback. I.e. your furnished library should be defined as
fooLib(int, char, void (*)(DataFormat, void *env));
void handler(DataFormat, void *env);
Now when you call fooLib, you furnish any struct at all as env, and it's passed back to you. This way you can dispense with the static variable in the wrapper:
// wrapped_foo_lib.c
typedef struct { WRAPPED_CALLBACK wrapped_callback; } ENV;
static void private_handler(DataFormat data, void *void_env) {
ENV *env = (ENV*)void_env;
NewDataFormat new_data = ...; // extract new_data from data
env->wrapped_callback(new_data);
}
void wrappedFooLibCall(int x, char c, WRAPPED_CALLBACK cb) {
ENV env[1] = {{ cb }};
foo_lib(x, c, env);
}
This is thread safe because ENV is stack allocated. A nice example of this done well is the libpng.
Feel free to update the C90 to more modern syntax.

How do I get SWIG to automatically wrap an emulated "this" pointer to a C struct?

I've got a simple C "class" I have implemented, using function pointers in a struct to implement the member functions, and passing a pointer to the struct as the first argument to each function, similar to the implicit "this" pointer in C++.
%module mytest
%{
typedef struct mytest mytest;
struct mytest {
int data;
int (*func1)(mytest *,int);
void (*func2)(mytest *,int);
};
int f1(mytest *me,int n) { return me->data + n; }
void f2(mytest *me,int n) { me->data += n; }
mytest *mytestNew(int n) {
mytest *me = (mytest*) malloc(sizeof(mytest));
me->data = n;
me->func1 = f1;
me->func2 = f2;
return me;
}
%}
typedef struct mytest mytest;
struct mytest {
int data;
int func1(mytest *,int);
void func2(mytest *,int);
};
extern mytest *mytestNew(int n);
Now my problem is, when the interface is created to whatever language I choose in the front end, I wind up having to explicitly pass the "this" pointer to the object, even though the language itself supports hiding this.
For instance, suppose I choose Python. I have to do something like this:
from mytest import *
m = mytestNew(1)
m.func1(m,0)
Where what I really want is to do it like this:
from mytest import *
m = mytestNew(1)
m.func1(0)
I know I could just write some wrapping code, but for my actual project I have a lot of functions in a lot of objects of existing C code, and multiplying this by every language that I want to support, this is just too much work! Is there some way to get SWIG to do this automatically?
You can do this in a language neutral way in SWIG with just two typemaps provided you name the parameter something consistent in the SWIG interface as well as the definitions to allow the typemaps to be applied selectively. (Unless you wanted all pointers to mytest to become "this" pointers by default of course)
The typemaps you need are:
// Make sure the wraqpped function doesn't expect an input for this:
%typemap(in,numinputs=0) mytest *me "$1=NULL;"
// Slightly abuse check typemap, but it needs to happen after the rest of the arguments have been set:
%typemap(check) mytest *me {
$1 = arg1;
}
The check typemap isn't really intended for use like this, but it's the easiest way to get the code to be injected after the arguments have been extracted from the target language and before the actual call is made.
You can also simplify the module with the help of a macro to avoid having to write and keep in sync the mapping between the function pointers and the members trick. I ended up with test.h as:
#ifdef SWIG
#define MEMBER(name, args) name args
#else
#define MEMBER(name, args) (*name) args
#endif
typedef struct mytest mytest;
struct mytest {
int data;
int MEMBER(func1,(mytest *me,int));
void MEMBER(func2,(mytest *me,int));
};
And the corresponding interface file (test.i):
%module test
%{
#include "test.h"
static int f1(mytest *me,int n) { return me->data + n; }
static void f2(mytest *me,int n) { me->data += n; }
%}
%extend mytest {
mytest(int n) {
$self->data = n;
$self->func1 = f1;
$self->func2 = f2;
}
}
%typemap(in,numinputs=0) mytest *me "$1=NULL;"
%typemap(check) mytest *me {
$1 = arg1;
}
%include "test.h"
(This interface file provides a constructor that "creates" the "object" exactly how a Java programmer would expect - you can call new and it sets the function pointers behind the scenes)

Resources