C++ 中的函数未接收到 Rust 中调用的正确参数

Kar*_*gro 5 c++ ffi extern rust

我正在尝试将 *.cc 链接到 Rust。

构建.rs:

fn main() {
    cc::Build::new()
        .file("src/bindings.cc")
        .cargo_metadata(true)
        .cpp(true)
        .compile("bindings");
}
Run Code Online (Sandbox Code Playgroud)

绑定.cc:

extern "C" {
    leveldb::Status db_get(
        LevelDB* db,
        const char* key, size_t keylen,
        const char** val, size_t* vallen,
        bool fillCache
    ) {
        printf("0: %p, 1: %p, 2: %d, 3: %p, 4: %p, 5: %s\n",
            db,
            key, keylen,
            val, vallen,
            fillCache ? "true" : "false"
        );
        leveldb::Status status;
        return status;
    }
}
Run Code Online (Sandbox Code Playgroud)

系统.rs:


enum LevelDB {}

// why? leveldb::Status has private property const char*
// It doesnt matter, this is just a test code
#[repr(C)]
struct Status(NonNull<u8>);

#[link(name = "bindings")]
extern "C" {
    pub fn db_get(
        db: *mut LevelDB,
        key: *const u8, keylen: usize,
        val: *mut *const u8, vallen: *mut usize,
        fill_cache: bool
    ) -> Status;
}
Run Code Online (Sandbox Code Playgroud)

我这样称呼它:

println!("0: {:?}, 1: {:?}, 2: {:?}, 3: {:?}, 4: {:?}, 5: {}",
    self.raw.as_ptr(),
    key.as_ptr(), key.len(),
    &mut val, &mut len,
    options.fill_cache
);

let status = sys::db_get(
    self.raw.as_ptr(),
    key.as_ptr(), key.len(),
    &mut val, &mut len,
    options.fill_cache
);
Run Code Online (Sandbox Code Playgroud)

现在,当我运行它时,它会打印:

0: 0x58aa2fc8a700, 1: 0x58aa2fc8a6e0, 2: 9, 3: 0x0, 4: 0, 5: true
0: 0x58aa2fc8a6e0, 1: 0x9, 2: 1439424216, 3: 0x7fff55cbdee0, 4: 0x1, 5: true
Run Code Online (Sandbox Code Playgroud)

每次我运行它时,指针可能会有所不同,但它仍然是相同的,与我打算在 Rust 代码中提供的内容不一致。我向你保证,我计算了 extern 函数参数类型大小,并确保它们在 Rust 方面相等,返回类型相同。我对其进行了调试并确保它们具有相同的大小。仅从观察来看,我可以看到论点向左移动。我无法确定问题所在