Rust FFI übergibt Merkmalsobjekt als Kontext zum Aufrufen von Rückrufen auf

Okay, ich versuche folgendes zu erreichen:

C ruft in Rostrust ruft c zurück und registriert einen Rückruf für ein benutzerdefiniertes Merkmalsobjektc ruft mit dem Kontext @ in Rorust ruft den Rückruf für den Kontext (Merkmalsobjekt) auf

Ich habe ziemlich viel damit gespielt. Ich bin ziemlich weit gekommen, aber immer noch nicht ganz da.

Das C-Bit:

#include <dlfcn.h>
#include <stdio.h>

void *global_ctx;

void c_function(void* ctx) {
    printf("Called c_function\n");
    global_ctx = ctx;
}

int main(void) {
    void *thing = dlopen("thing/target/debug/libthing.dylib", RTLD_NOW | RTLD_GLOBAL);
    if (!thing) {
        printf("error: %s\n", dlerror());
        return 1;
    }
    void (*rust_function)(void) = dlsym(thing, "rust_function");
    void (*rust_cb)(void*) = dlsym(thing, "rust_cb");
    printf("rust_function = %p\n", rust_function);
    rust_function();

    rust_cb(global_ctx);
}

Das Roststückchen:

extern crate libc;


pub trait Foo {
    fn callback(&self);
}

extern {
    fn c_function(context: *mut libc::c_void);
}

pub struct MyFoo;
impl Foo for MyFoo {
    fn callback(&self) {
        println!("callback on trait");
    }
}

#[no_mangle]
pub extern fn rust_cb(context: *mut Foo) {
    unsafe {
        let cb:Box<Foo> = Box::from_raw(context);
        cb.callback();
    }
}

#[no_mangle]
pub extern fn rust_function() {
    println!("Called rust_function");
    let tmp = Box::new(MyFoo);
    unsafe {
        c_function(Box::into_raw(tmp) as *const Foo as *mut libc::c_void);
    }
}

Die Angelegenheit

Mein Programm schlägt fehl, wenn ich versuche, "callback" für das Merkmalobjekt in "rust_cb" aufzurufen

Eine Lösung: - Ändern Sie die Funktionssignatur von "rust_cb" in

pub extern fn rust_cb(context: *mut MyFoo)

Aber das ist nicht das, was ich will, da ich versuche, einen sicheren Wrapper zu erstellen, der nur die Eigenschaften des Hörers kennt.

Jede Hilfe dankbar

PS: Ich gehe davon aus, dass der Fehler auftritt, da der Compiler den Offset des Rückrufs für das Merkmal Foo nicht kennt. Er benötigt das eigentliche Objekt, um zu bestimmen, wo es sich befindet. aber dann habe ich keine ahnung, wie ich das umgehen soll

Antworten auf die Frage(4)

Ihre Antwort auf die Frage