Rust FFI指南(http://static.rust-lang.org/doc/master/guide-ffi.html)很好地演示了如何导入使用由Rust std::lib库包装的标准C类型的C函数,例如size_t.但是如何将第三方库中定义的C数据结构引入Rust程序?
我正在使用libmemcached,它具有以下功能:
memcached_st* memcached_create(memcached_st *ptr)
Run Code Online (Sandbox Code Playgroud)
这通常在C程序中被调用(为了解决问题):
#include <libmemcached/memcached.h>
// ...
memcached_st *memc;
memc = memcached_create(NULL);
Run Code Online (Sandbox Code Playgroud)
这memcached_st是一个不透明的C结构 - 如何在Rust程序中声明和使用它?以下是我到目前为止失败的尝试:
use std::libc::*;
use ptr;
#[link(name = "memcached")]
extern {
struct memcached_st; // error: unexpected token: `struct`
memcached_st* memcached_create(memcached_st *ptr);
}
fn main() {
unsafe {
let memc = memcached_create(ptr:null());
println!("{:?}", memc);
}
}
Run Code Online (Sandbox Code Playgroud)
和
use std::libc::*;
use ptr;
#[link(name = "memcached")]
extern {
// error: unexpected token: `memcached_st`
memcached_st* memcached_create(memcached_st *ptr); …Run Code Online (Sandbox Code Playgroud) 我有一个返回指针的C函数:
type MYSQL_RES_REF = *mut c_void;
type MYSQL_ROW = *const *const c_char;
#[no_mangle]
extern "C" {
fn mysql_fetch_row(res: MYSQL_RES_REF) -> MYSQL_ROW;
}
let pointer = mysql_fetch_row(self.res);
let row_p = match pointer {
p if p == (0 as *const *const c_char) => panic!(),
p => p,
};
let field: &[u8] = unsafe { ffi::c_str_to_bytes(row_p[i]) };
Run Code Online (Sandbox Code Playgroud)
但尝试索引它(最后一行)会导致错误:
error: cannot index a value of type `*const *const i8`
Run Code Online (Sandbox Code Playgroud)
我想知道std::c_vec是不是我想要的,但显然已被删除.
给定一个结构:
#[repr(C)]
pub struct User {
pub name: *const c_char,
pub age: u8,
pub ctx: ??,
}
Run Code Online (Sandbox Code Playgroud)
该字段ctx只能由C代码操作;它是C结构的指针UserAttr。
根据Rust FFI文档,该选择将定义为不透明类型pub enum UserAttr {}。但是,我发现Rust无法复制其值,例如,为什么对象的地址在方法之间会发生变化。
在Rust中定义这样一个不透明指针的正确方法是什么,以使它的值(作为指针)跨方法复制?