Q:

Using reference to type parameter in callback function of C library

I am writing a Rust interface to a C library that has a function with the following signature:
typedef int (*callback_t)(const int *a, void *user_data);
void execute(callback_t callback);

What I would like is that the users of the Rust interface can pass any type T for user_data (user_data is not used in the C library). In other words, on the Rust side I would like:
type Callback<T> = fn(a: &mut usize, user_data: &mut T) -> usize;

I tried casting a user-defined Rust function of type Callback<T> to
extern "C" fn callback(a: *mut c_int, user_data: *mut c_void) -> c_int

with as, but that does not work. I also tried to create a wrapping closure. Both attempts did not work.
Can anyone help me out?

A:

You should not be casting function pointers between different signatures.  That's catastrophically unsafe and will blow your program up (if you're lucky).  Function pointers are not interchangeable, and the compiler cannot magically make them compatible.
What you're effectively doing here is taking an order written in Italian, scratching out "language = Italian", replacing it with "language = Russian", and expecting the Russian chef to understand it because, hey, it says it's in Russian!
First of all, your translation of the raw C type is probably wrong.  The first argument is *const c_int, not *mut c_int.  C does allow you to cast const away, but it's rarely something the other code will expect.
Secondly, you should not translate raw C pointers as safe Rust references.  If the C code calls with a null pointer, your Rust code will have undefined behaviour.  Unless the C library guarantees that both pointers are never null with a contract signed in blood and guaranteed with the programmer's first born child, don't trust it: check the pointers first.
Third, c_int and usize are not the same type.  Do not conflate them.  The correct type to use for the Rust interface is c_int.
So the actual C callback type in Rust is:
type CCallback = Option<extern "C" fn(a: *const c_int, user_data: *mut c_void) -> c_int>;

The Option is there because C function pointers can be null, in Rust they can't.
Finally, Callback<T> isn't marked with extern "C".  Getting the calling convention exactly right is of critical importance.
The signature of any function you intend to cast to the C callback type should be exactly the C callback signature.  That is:
extern "C" fn a_callback(a: *const c_int, user_data: *mut c_void) -> c_int {
    ::std::process::abort();
}

Now, you might be able to get away with this:
extern "C" fn a_callback<T>(a: *const c_int, user_data: *mut T) -> c_int {
    ::std::process::abort();
}

And coerce Some(a_callback) to CCallback.  That said, I can't guarantee this is correct for all possible T.
To be safe, you should explicitly wrap all Rust callback functions in a translation function.  This is most easily done with a macro that, given the name of the Rust function, generates a C shim.
macro_rules! shim {
    ($c:ident => $r:ident) => {
        extern "C" fn $c(a: *const c_int, user_data: *mut c_void) -> c_int {
            if a.is_null() {
                ::std::process::abort()
            }
            if user_data.is_null() {
                ::std::process::abort()
            }
            // NOTE: You need to make *absolutely certain* that this cast
            // of user_data is valid.
            let res: i32 = $r(&*a, &mut *(user_data as *mut _));
            res as c_int
        }
    };
}

shim!(another_callback_c => another_callback);

fn another_callback(a: &c_int, user_data: &mut u8) -> i32 {
    // Do something...
    ::std::process::abort()
}

