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
I am working with the xinu embedded operating system in c. I created a new header file and declared a struct:
struct callout {
uint32 time; /* Time of delay in ms */
void *funcaddr; /* Function pointer */
void *argp; /* Function arguments */
uint32 cid; /* Callout id for the specific callout */
char *sample;
};
In my main, I try to declare a struct object and function the funcaddr to a function.
void test();
process main(void) {
struct callout *coptr;
coptr->sample ="hellowolrd";
coptr->funcaddr = &test;
(coptr->funcaddr)(coptr->argp); //error here
kprintf("coptr %s \n", coptr->sample);
return OK;
}
void test() {
kprintf("this is the test function \n");
}
I try to invoke the function pointer through the struct but I am getting an error:
main.c:30:19: error: called object is not a function or function pointer
(coptr->funcaddr)();
Please show what is the correct syntax to invoke the function pointer.
You have declared funcaddr as an object pointer. To declare a function pointer it looks like this:
struct callout {
uint32 time;
void (*funcaddr)(); // <-------- function pointer
Then the rest of your code should work.
If you didn't see an error message for the line coptr->funcaddr = &test; then I would recommend adjusting your compiler settings, it's important to have the information available that the compiler can tell you.
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.
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.
I've seen both of the following two styles of declaring opaque types in C APIs. What are the various ways to declare opaque structs/pointers in C? Is there any clear advantage to using one style over the other?
Option 1
// foo.h
typedef struct foo * fooRef;
void doStuff(fooRef f);
// foo.c
struct foo {
int x;
int y;
};
Option 2
// foo.h
typedef struct _foo foo;
void doStuff(foo *f);
// foo.c
struct _foo {
int x;
int y;
};
My vote is for the third option that mouviciel posted then deleted:
I have seen a third way:
// foo.h
struct foo;
void doStuff(struct foo *f);
// foo.c
struct foo {
int x;
int y;
};
If you really can't stand typing the struct keyword, typedef struct foo foo; (note: get rid of the useless and problematic underscore) is acceptable. But whatever you do, never use typedef to define names for pointer types. It hides the extremely important piece of information that variables of this type reference an object which could be modified whenever you pass them to functions, and it makes dealing with differently-qualified (for instance, const-qualified) versions of the pointer a major pain.
Option 1.5 ("Object-based" C Architecture):
I am accustomed to using Option 1, except where you name your reference with _h to signify it is a "handle" to a C-style "object" of this given C "class". Then, you ensure your function prototypes use const wherever the content of this object "handle" is an input only, and cannot be changed, and don't use const wherever the content can be changed. So, do this style:
// -------------
// my_module.h
// -------------
// An opaque pointer (handle) to a C-style "object" of "class" type
// "my_module" (struct my_module_s *, or my_module_h):
typedef struct my_module_s *my_module_h;
void doStuff1(my_module_h my_module);
void doStuff2(const my_module_h my_module);
// -------------
// my_module.c
// -------------
// Definition of the opaque struct "object" of C-style "class" "my_module".
struct my_module_s
{
int int1;
int int2;
float f1;
// etc. etc--add more "private" member variables as you see fit
};
Here's a full example using opaque pointers in C to create objects. The following architecture might be called "object-based C":
//==============================================================================================
// my_module.h
//==============================================================================================
// An opaque pointer (handle) to a C-style "object" of "class" type "my_module" (struct
// my_module_s *, or my_module_h):
typedef struct my_module_s *my_module_h;
// Create a new "object" of "class" "my_module": A function that takes a *pointer to* an
// "object" handle, `malloc`s memory for a new copy of the opaque `struct my_module_s`, then
// points the user's input handle (via its passed-in pointer) to this newly-created "object" of
// "class" "my_module".
void my_module_open(my_module_h * my_module_h_p);
// A function that takes this "object" (via its handle) as an input only and cannot modify it
void my_module_do_stuff1(const my_module_h my_module);
// A function that can modify the private content of this "object" (via its handle) (but still
// cannot modify the handle itself)
void my_module_do_stuff2(my_module_h my_module);
// Destroy the passed-in "object" of "class" type "my_module": A function that can close this
// object by stopping all operations, as required, and `free`ing its memory.
void my_module_close(my_module_h my_module);
//==============================================================================================
// my_module.c
//==============================================================================================
// Definition of the opaque struct "object" of C-style "class" "my_module".
// - NB: Since this is an opaque struct (declared in the header but not defined until the source
// file), it has the following 2 important properties:
// 1) It permits data hiding, wherein you end up with the equivalent of a C++ "class" with only
// *private* member variables.
// 2) Objects of this "class" can only be dynamically allocated. No static allocation is
// possible since any module including the header file does not know the contents of *nor the
// size of* (this is the critical part) this "class" (ie: C struct).
struct my_module_s
{
int my_private_int1;
int my_private_int2;
float my_private_float;
// etc. etc--add more "private" member variables as you see fit
};
void my_module_open(my_module_h * my_module_h_p)
{
// Ensure the passed-in pointer is not NULL (since it is a core dump/segmentation fault to
// try to dereference a NULL pointer)
if (!my_module_h_p)
{
// Print some error or store some error code here, and return it at the end of the
// function instead of returning void.
goto done;
}
// Now allocate the actual memory for a new my_module C object from the heap, thereby
// dynamically creating this C-style "object".
my_module_h my_module; // Create a local object handle (pointer to a struct)
// Dynamically allocate memory for the full contents of the struct "object"
my_module = malloc(sizeof(*my_module));
if (!my_module)
{
// Malloc failed due to out-of-memory. Print some error or store some error code here,
// and return it at the end of the function instead of returning void.
goto done;
}
// Initialize all memory to zero (OR just use `calloc()` instead of `malloc()` above!)
memset(my_module, 0, sizeof(*my_module));
// Now pass out this object to the user, and exit.
*my_module_h_p = my_module;
done:
}
void my_module_do_stuff1(const my_module_h my_module)
{
// Ensure my_module is not a NULL pointer.
if (!my_module)
{
goto done;
}
// Do stuff where you use my_module private "member" variables.
// Ex: use `my_module->my_private_int1` here, or `my_module->my_private_float`, etc.
done:
}
void my_module_do_stuff2(my_module_h my_module)
{
// Ensure my_module is not a NULL pointer.
if (!my_module)
{
goto done;
}
// Do stuff where you use AND UPDATE my_module private "member" variables.
// Ex:
my_module->my_private_int1 = 7;
my_module->my_private_float = 3.14159;
// Etc.
done:
}
void my_module_close(my_module_h my_module)
{
// Ensure my_module is not a NULL pointer.
if (!my_module)
{
goto done;
}
free(my_module);
done:
}
Simplified example usage:
#include "my_module.h"
#include <stdbool.h>
#include <stdio.h>
int main()
{
printf("Hello World\n");
bool exit_now = false;
// setup/initialization
my_module_h my_module = NULL;
// For safety-critical and real-time embedded systems, it is **critical** that you ONLY call
// the `_open()` functions during **initialization**, but NOT during normal run-time,
// so that once the system is initialized and up-and-running, you can safely know that
// no more dynamic-memory allocation, which is non-deterministic and can lead to crashes,
// will occur.
my_module_open(&my_module);
// Ensure initialization was successful and `my_module` is no longer NULL.
if (!my_module)
{
// await connection of debugger, or automatic system power reset by watchdog
log_errors_and_enter_infinite_loop();
}
// run the program in this infinite main loop
while (exit_now == false)
{
my_module_do_stuff1(my_module);
my_module_do_stuff2(my_module);
}
// program clean-up; will only be reached in this case in the event of a major system
// problem, which triggers the infinite main loop above to `break` or exit via the
// `exit_now` variable
my_module_close(my_module);
// for microcontrollers or other low-level embedded systems, we can never return,
// so enter infinite loop instead
while (true) {}; // await reset by watchdog
return 0;
}
The only improvements beyond this would be to:
Implement full error handling and return the error instead of void. Ex:
/// #brief my_module error codes
typedef enum my_module_error_e
{
/// No error
MY_MODULE_ERROR_OK = 0,
/// Invalid Arguments (ex: NULL pointer passed in where a valid pointer is required)
MY_MODULE_ERROR_INVARG,
/// Out of memory
MY_MODULE_ERROR_NOMEM,
/// etc. etc.
MY_MODULE_ERROR_PROBLEM1,
} my_module_error_t;
Now, instead of returning a void type in all of the functions above and below, return a my_module_error_t error type instead!
Add a configuration struct called my_module_config_t to the .h file, and pass it in to the open function to update internal variables when you create a new object. This helps encapsulate all configuration variables in a single struct for cleanliness when calling _open().
Example:
//--------------------
// my_module.h
//--------------------
// my_module configuration struct
typedef struct my_module_config_s
{
int my_config_param_int;
float my_config_param_float;
} my_module_config_t;
my_module_error_t my_module_open(my_module_h * my_module_h_p,
const my_module_config_t *config);
//--------------------
// my_module.c
//--------------------
my_module_error_t my_module_open(my_module_h * my_module_h_p,
const my_module_config_t *config)
{
my_module_error_t err = MY_MODULE_ERROR_OK;
// Ensure the passed-in pointer is not NULL (since it is a core dump/segmentation fault
// to try to dereference a NULL pointer)
if (!my_module_h_p)
{
// Print some error or store some error code here, and return it at the end of the
// function instead of returning void. Ex:
err = MY_MODULE_ERROR_INVARG;
goto done;
}
// Now allocate the actual memory for a new my_module C object from the heap, thereby
// dynamically creating this C-style "object".
my_module_h my_module; // Create a local object handle (pointer to a struct)
// Dynamically allocate memory for the full contents of the struct "object"
my_module = malloc(sizeof(*my_module));
if (!my_module)
{
// Malloc failed due to out-of-memory. Print some error or store some error code
// here, and return it at the end of the function instead of returning void. Ex:
err = MY_MODULE_ERROR_NOMEM;
goto done;
}
// Initialize all memory to zero (OR just use `calloc()` instead of `malloc()` above!)
memset(my_module, 0, sizeof(*my_module));
// Now initialize the object with values per the config struct passed in. Set these
// private variables inside `my_module` to whatever they need to be. You get the idea...
my_module->my_private_int1 = config->my_config_param_int;
my_module->my_private_int2 = config->my_config_param_int*3/2;
my_module->my_private_float = config->my_config_param_float;
// etc etc
// Now pass out this object handle to the user, and exit.
*my_module_h_p = my_module;
done:
return err;
}
And usage:
my_module_error_t err = MY_MODULE_ERROR_OK;
my_module_h my_module = NULL;
my_module_config_t my_module_config =
{
.my_config_param_int = 7,
.my_config_param_float = 13.1278,
};
err = my_module_open(&my_module, &my_module_config);
if (err != MY_MODULE_ERROR_OK)
{
switch (err)
{
case MY_MODULE_ERROR_INVARG:
printf("MY_MODULE_ERROR_INVARG\n");
break;
case MY_MODULE_ERROR_NOMEM:
printf("MY_MODULE_ERROR_NOMEM\n");
break;
case MY_MODULE_ERROR_PROBLEM1:
printf("MY_MODULE_ERROR_PROBLEM1\n");
break;
case MY_MODULE_ERROR_OK:
// not reachable, but included so that when you compile with
// `-Wall -Wextra -Werror`, the compiler will fail to build if you forget to handle
// any of the error codes in this switch statement.
break;
}
// Do whatever else you need to in the event of an error, here. Ex:
// await connection of debugger, or automatic system power reset by watchdog
while (true) {};
}
// ...continue other module initialization, and enter main loop
See also:
[another answer of mine which references my answer above] Architectural considerations and approaches to opaque structs and data hiding in C
Additional reading on object-based C architecture:
Providing helper functions when rolling out own structures
Additional reading and justification for valid usage of goto in error handling for professional code:
An argument in favor of the use of goto in C for error handling: https://github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles/blob/master/Research_General/goto_for_error_handling_in_C/readme.md
*****EXCELLENT ARTICLE showing the virtues of using goto in error handling in C: "Using goto for error handling in C" - https://eli.thegreenplace.net/2009/04/27/using-goto-for-error-handling-in-c
Valid use of goto for error management in C?
Error handling in C code
Search terms to make more googlable: opaque pointer in C, opaque struct in C, typedef enum in C, error handling in C, c architecture, object-based c architecture, dynamic memory allocation at initialization architecture in c
bar(const fooRef) declares an immutable address as argument. bar(const foo *) declares an address of an immutable foo as argument.
For this reason, I tend to prefer option 2. I.e., the presented interface type is one where cv-ness can be specified at each level of indirection. Of course one can sidestep the option 1 library writer and just use foo, opening yourself to all sorts of horror when the library writer changes the implementation. (I.e., the option 1 library writer only perceives that fooRef is part of the invariant interface and that foo can come, go, be altered, whatever. The option 2 library writer perceives that foo is part of the invariant interface.)
I'm more surprised that no one's suggested combined typedef/struct constructions.
typedef struct { ... } foo;
Option 3: Give people choice
/* foo.h */
typedef struct PersonInstance PersonInstance;
typedef struct PersonInstance * PersonHandle;
typedef const struct PersonInstance * ConstPersonHandle;
void saveStuff (PersonHandle person);
int readStuff (ConstPersonHandle person);
...
/* foo.c */
struct PersonInstance {
int a;
int b;
...
};
...