当Rust FFI函数将没有#[repr(C)]的结构返回给C时,会返回什么?
编辑:有人指出,我的示例不够完整,没有什么用处。我的问题已经解决了,但是如果您对查看完整的代码感兴趣,您可以看到它 给定以下代码:当Rust FFI函数将没有#[repr(C)]的结构返回给C时,会返回什么?,rust,ffi,Rust,Ffi,编辑:有人指出,我的示例不够完整,没有什么用处。我的问题已经解决了,但是如果您对查看完整的代码感兴趣,您可以看到它 给定以下代码: #[无损坏] pub extern“C”fn create_acceptor()->acceptor{ 受体{} } 发布结构接受程序{} 如果我从C中调用它,它实际上得到了什么?是指针吗?某种身份证 我目前在C端使用的代码如下: extern int create_acceptor(); int main(int argc,字符**argv){ int acce
#[无损坏]
pub extern“C”fn create_acceptor()->acceptor{
受体{}
}
发布结构接受程序{}
如果我从C中调用它,它实际上得到了什么?是指针吗?某种身份证
我目前在C端使用的代码如下:
extern int create_acceptor();
int main(int argc,字符**argv){
int acceptor=create_acceptor();
返回0;
}
它似乎工作得很好。我像使用不透明类型一样使用它,然后将其传回Rust,比如acceptor\u doSomething(acceptor)
但是我很困惑,因为我在C端使用什么类型的接受器
,似乎并不重要void*
和int
的行为相同。此外,文档似乎表明我应该使用#[repr(C)]
,但没有它似乎也可以工作。为什么呢
当打印C端收到的值时,它显示的是非常小的整数,所以我猜它是生锈端的一个id?TL;DR:这个例子没有什么用处,也没有说明什么 它到底得到了什么?是指针吗?某种身份证 这是一个结构,与锈面上的定义完全一致。如果返回指针(本例不返回),则为指针;如果返回某个id,则为id(本例不返回) Rust的FFI没有强加任何开销或抽象——您返回的就是返回的 文档似乎表明我应该使用
#[repr(C)]
是的,你应该。没有它,代码很可能是未定义的行为。Rust结构的布局尚未得到保证。如果不将表示形式指定为C,C代码就无法知道哪些字段在哪里
但如果没有它,它似乎会起作用
这是因为示例结构没有字段,因此没有大小(如果没有非标准扩展,AFAIK在C中甚至都无效)。Rust基本上不需要查看数据(什么数据?),所以您传递回什么并不重要
当打印在C端收到的值时,它显示的是非常小的整数
这可能只是堆积如山的垃圾。实际上是未初始化的数据
使用不带#[repr(C)]
这是坏的。不要这样做<代码>字符串是一个具有非平凡字段的结构,它没有标记为#[repr(C)]
Cargo.toml
[软件包]
name=“剪切”
version=“0.1.0”
作者=[“开发者”]
[lib]
板条箱类型=[“cdylib”]
[依赖关系]
src/lib.rs
// Don't do this, `String` isn't #[repr(C)]!
#[no_mangle]
pub extern "C" fn create_example() -> String {
String::from("hello")
}
// Don't do this, `String` isn't #[repr(C)]!
#[no_mangle]
pub extern "C" fn use_example(e: String) {
println!("{}", e);
}
main.c
extern int create_example();
外部无效使用示例(内部示例);
int main(int argc,字符**argv){
int example=create_example();
使用示例(示例);
}
执行
$cargo build
编译剪切机v0.1.0(file:///home/ubuntu/shear)
在1.02s内完成开发[未优化+调试信息]目标
$gcc-o示例main.c-L目标/debug/-lshear
$LD\u LIBRARY\u PATH=target/debug//example
分段故障
有关如何正确地跨FFI边界传输值的详细信息,请阅读。免责声明:我是主要作者。TL;DR:这个例子没有什么用处,也没有说明什么 它到底得到了什么?是指针吗?某种身份证 这是一个结构,与锈面上的定义完全一致。如果返回指针(本例不返回),则为指针;如果返回某个id,则为id(本例不返回) Rust的FFI没有强加任何开销或抽象——您返回的就是返回的 文档似乎表明我应该使用
#[repr(C)]
是的,你应该。没有它,代码很可能是未定义的行为。Rust结构的布局尚未得到保证。如果不将表示形式指定为C,C代码就无法知道哪些字段在哪里
但如果没有它,它似乎会起作用
这是因为示例结构没有字段,因此没有大小(如果没有非标准扩展,AFAIK在C中甚至都无效)。Rust基本上不需要查看数据(什么数据?),所以您传递回什么并不重要
当打印在C端收到的值时,它显示的是非常小的整数
这可能只是堆积如山的垃圾。实际上是未初始化的数据
使用不带#[repr(C)]
这是坏的。不要这样做<代码>字符串是一个具有非平凡字段的结构,它没有标记为#[repr(C)]
Cargo.toml
[软件包]
name=“剪切”
version=“0.1.0”
作者=[“开发者”]
[lib]
板条箱类型=[“cdylib”]
[依赖关系]
src/lib.rs
// Don't do this, `String` isn't #[repr(C)]!
#[no_mangle]
pub extern "C" fn create_example() -> String {
String::from("hello")
}
// Don't do this, `String` isn't #[repr(C)]!
#[no_mangle]
pub extern "C" fn use_example(e: String) {
println!("{}", e);
}
main.c
extern int create_example();
外部无效使用示例(内部示例);
int main(int argc,字符**argv){
int example=create_example();
使用示例(示例);
}
执行
$cargo build
编译剪切机v0.1.0(file:///home/ubuntu/shear)
在1.02s内完成开发[未优化+调试信息]目标
$gcc-o示例main.c-L目标/debug/-lshear
$LD\u LIBRARY\u PATH=target/debug//example
分段故障
有关如何正确地跨FFI边界传输值的详细信息,请阅读。免责声明:我是主要作者。是的,我简化了示例以减少噪音。显然我剪得太多了。在我的实际代码中,我存储了非平凡的数据(TcpListener和TcpStream)和aft