Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
当Rust FFI函数将没有#[repr(C)]的结构返回给C时,会返回什么?_Rust_Ffi - Fatal编程技术网

当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