The equivalent of a function pointer in C is the bare fn type in rust. For
example, you could write your binding as:

  // C code
  int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n,
                        void(*)(void*));

  // Rust definition
  fn sqlite3_bind_text(stmt: *mut sqlite3_stmt,
                       arg1: libc::c_int,
                       arg2: *libc::c_char,
                       arg3: libc::c_int,
                       arg4: extern fn(*mut libc::c_void)) -> libc::c_int;

You'll note that "extern" means use the default foreign ABI, as the rust ABI is
different than the C ABI. The two types you were trying, procedures and
closures, have environments attached to them which is likely what the C function
is not expecting. The "extern fn()" type is rust's function pointer type.

Notably, however, values of "extern fn()" are assumed to be non-null by the
compiler, so the interop with your C library may not be perfect because
SQLITE_STATIC cannot have a value of "extern fn()" (as it would be null).

To work around this, Rust has a null-pointer optimization where
Option<extern fn()> is optimized to a nullable pointer in terms of
representation. There are currently some issues with ABI compatibility, but
these will likely be addressed in the near future!

On Tue, May 13, 2014 at 2:17 PM, Christophe Pedretti
<[email protected]> wrote:
> Hi all,
>
> SQLITE is defining the following C function :
> int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*));
>
> How to include it in an extern block ?
> I have tried this
> fn sqlite3_bind_text(pStmt : *mut(), iCol : c_int, value : *c_char, n
> : c_int, f :  *proc(*())) -> c_int;
> (a pointer to a function taking a pointer as an argument)
> i have also tried
> fn sqlite3_bind_text(pStmt : *mut(), iCol : c_int, value : *c_char, n
> : c_int, f :  *|*()|) -> c_int;
>
> In SQLITE, this argument can takes value SQLITE_STATIC or SQLITE_TRANSIENT
> typedef void (*sqlite3_destructor_type)(void*);
> #define SQLITE_STATIC      ((sqlite3_destructor_type)0)
> #define SQLITE_TRANSIENT   ((sqlite3_destructor_type)-1)
>
> for example, how to set this argument to SQLITE_STATIC in Rust ?
>
> Thanks
>
> --
> Christophe
> http://chris-pe.github.io/Rustic/
> _______________________________________________
> Rust-dev mailing list
> [email protected]
> https://mail.mozilla.org/listinfo/rust-dev
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to