将 Rust 变量传递给期望能够修改它的 C 函数

     2023-02-19     246

关键词:

【中文标题】将 Rust 变量传递给期望能够修改它的 C 函数【英文标题】:Passing a Rust variable to a C function that expects to be able to modify it 【发布时间】:2017-08-01 08:41:16 【问题描述】:

我正在编写一个安全的 Rust 层,我可以使用它调用 Rust 中的 C 库中的函数。我已经使用rust-bindgen 生成了不安全的绑定,但是对于 Rust 和 C 在传递指针方面的工作方式之间的差异,我有点困惑。

C 函数如下所示:

bool imeGet(unsigned char address, int *value);

它读取address 的I2C 传感器,将结果存储在value,并在成功时返回TRUE

Bindgen 的 Rust 函数如下所示:

pub fn imeGet(address: ::std::os::raw::c_uchar,
              value: *mut ::std::os::raw::c_int) -> bool;

我的安全呼叫者目前看起来像这样:

pub fn ime_get(addr: u8) -> i32 
    let v: &mut i32 = 0;
    unsafe 
        imeGet(addr, v);
        *v
    

由于= 0,此代码无法编译。当我没有那个时,编译器抱怨v 可能没有被初始化。我的意图是在这个函数中处理成功,并返回 i32 值。

如何处理*mut c_int 参数的行为?我试图将v 声明为引用并返回其取消引用的值(上图),但这不起作用。我也尝试只返回 v,但我真的不希望返回值保持可变。

我对 Rust 很陌生,但我确实有不错的 C 语言背景,这可能是我困惑的根源。

【问题讨论】:

【参考方案1】:

但我在 C 方面确实有不错的背景

你的 Rust 代码的道德等价物是:

int *v = NULL;
imeGet(addr, v);
*v

这将产生一个错误,因为 C 代码可能会取消引用 v 以将值存储在其中,除非您传入了 NULL,因此它更有可能实现繁荣。

您需要为该值创建存储,然后向函数提供对该存储的引用:

fn ime_get(addr: u8) -> i32 
    let mut v = 0;
    unsafe  imeGet(addr, &mut v) ;
    v

任何指针类型的解决方案都使用ptr::null_mut

unsafe  
    let mut v = std::ptr::null_mut();
    takes_a_pointer_pointer(addr, &mut v);
    v

任何类型的通用解决方案使用mem::MaybeUninit

unsafe 
    let mut v = std::mem::MaybeUninit::uninit();
    takes_a_value_pointer(addr, v.as_mut_ptr());
    v.assume_init()

为了完整性,您应该检查返回值:

fn ime_get(addr: u8) -> Option<i32> 
    let mut v = 0;
    let success = unsafe  imeGet(addr, &mut v) ;

    if success 
        Some(v)
     else 
        None
    

Rust 和 C 在传递指针方面的工作方式之间的差异。

在这个级别上真的没有。

【讨论】:

哎呀,不知道我在想什么。谢谢!

将继承的类对象的向量传递给期望基类向量的函数

...自opencvRect的A类。A只是添加了一些我想在执行期间跟踪的变量。classA:publicRect//code,constructors...我想使用opencv 查看详情

提供者更新变量,但旧值被传递给依赖它的函数

】提供者更新变量,但旧值被传递给依赖它的函数【英文标题】:Providerupdatesvariable,buttheoldvalueispassedintofunctionthatdependonit【发布时间】:2021-01-2122:15:24【问题描述】:我正在使用提供程序将输入字段的值存储在表单中。在save()方... 查看详情

如何将变量结构类型传递给 C 中的函数

】如何将变量结构类型传递给C中的函数【英文标题】:HowdoIpassavariablestructtypetoafunctioninC【发布时间】:2021-08-2804:32:56【问题描述】:我想创建一个fireandforget函数来处理链表的所有元素所持有的内存空间。它需要三个参数,一个... 查看详情

将 Eigen::Map<ArrayXd> 传递给期望 ArrayXd& 的函数

】将Eigen::Map<ArrayXd>传递给期望ArrayXd&的函数【英文标题】:PassingEigen::Map<ArrayXd>toafunctionexpectingArrayXd&【发布时间】:2014-03-0509:26:43【问题描述】:我的一些EigenC++方法需要可以从普通C++调用,因此我想提供接受c数... 查看详情

在c语言中,函数实参与形参之间的数据传递方式是()传递方式。

...,只使用了实参的值。传值调用机制里,形参是一个局部变量,其初始值为相应实参的值。在引用调用机制里,将实参的地址传递给形参,从表面上看是以实参变量取代形参,因此任何发生在形参上的改变实际上都发生在实参变... 查看详情

将结构变量传递给函数

】将结构变量传递给函数【英文标题】:passingstructurevariabletofunction【发布时间】:2015-02-1223:20:36【问题描述】:我正在研究C编程中的结构。但是,我对这段代码感到困惑,所以我不明白。函数中的b来自哪里?怎么会是这样使用... 查看详情

如何将表达式传递给 JavaScript 函数

】如何将表达式传递给JavaScript函数【英文标题】:HowtopassanexpressionintoJavaScriptfunction【发布时间】:2019-12-1317:59:46【问题描述】:我有2个类对象:leta,letb,每个对象都有一个键“值”。我希望能够创建第三个对象letc并计算它的... 查看详情

C# - 将变量传递给另一个表单

】C#-将变量传递给另一个表单【英文标题】:C#-passingavariabletoanotherform【发布时间】:2022-01-1515:34:06【问题描述】:我试图将Useruser变量传递给另一个表单,但由于某种原因,它说它的值是null。我做错了什么?AuthorizationForm.cs:pu... 查看详情

c语言函数参数传递方向

...技术AC语言中函数参数传递的三种方式(1)传值,就是把你的变量的值传递给函数的形式参数,实际就是用变量的值来新生成一个形式参数 参考技术BC语言函数你必须通过它的传递的方向,你才能查出来它的函数的那种呃算出的那个... 查看详情

C:将数组“即时”传递给函数

...,我想将一个char*数组传递给它,但我不想为此创建一个变量,如下所示:char*bar[]="aa","bb","cc";foobar=foo(bar);为了解决这个问题,我尝试了这个:foobar=foo("aa","bb","cc" 查看详情

如何修改已传递给 C 函数的指针?

】如何修改已传递给C函数的指针?【英文标题】:HowdoImodifyapointerthathasbeenpassedintoafunctioninC?【发布时间】:2010-10-2011:52:42【问题描述】:所以,我有一些类似于下面的代码,用于将结构添加到结构列表中:voidbarPush(BarList*list,Bar*... 查看详情

C / C ++:将带有成员数组的结构/类按值传递给函数

】C/C++:将带有成员数组的结构/类按值传递给函数【英文标题】:C/C++:passingastruct/classwithamemberarraytoafunctionbyvalue【发布时间】:2015-09-2418:22:02【问题描述】:structAintV[100];;voidf(Aa)a.V[0]=30;intmain()Aa;a.V[0]=10;f(a);cout<<a.V[0];我期望3... 查看详情

将结构传递给函数

】将结构传递给函数【英文标题】:Passingstructtofunction【发布时间】:2012-05-0908:20:48【问题描述】:我是一名新的C程序员,我想知道如何将struct传递给函数。我遇到了一个错误,无法找出正确的语法来做到这一点。这是它的代码... 查看详情

将指向局部变量的指针传递给函数:它安全吗?

】将指向局部变量的指针传递给函数:它安全吗?【英文标题】:Passingpointertolocalvariabletofunction:isitsafe?【发布时间】:2015-04-1721:15:32【问题描述】:例如:voidfunc1()inti=123;func2(&i);voidfunc2(int*a)*a=456;当func1调用func2时,将一个指... 查看详情

如何将变量传递给评估函数?

】如何将变量传递给评估函数?【英文标题】:HowcanIpassvariableintoanevaluatefunction?【发布时间】:2017-09-0705:17:33【问题描述】:我正在尝试将变量传递给Puppeteer中的page.evaluate()函数,但是当我使用以下非常简化的示例时,变量evalVa... 查看详情

将类型变量传递给函数

】将类型变量传递给函数【英文标题】:Passinginatypevariableintofunction【发布时间】:2017-04-1505:18:23【问题描述】:我试图通过将类型传递给函数来实现类型断言。换句话说,我正在尝试实现这样的目标://Notethatthisispseudocode,becauseT... 查看详情

使用 emscripten 将数组传递给 C 函数

】使用emscripten将数组传递给C函数【英文标题】:PassarraytoCfunctionwithemscripten【发布时间】:2016-10-1709:41:04【问题描述】:我认为这个问题与thisone类似,我使用了它的大部分答案来解决我的问题,但我仍然有问题:首先是C代码:#... 查看详情

将 JavaScript 回调传递给在另一个线程中调用它的 FFI 函数是不是安全?

】将JavaScript回调传递给在另一个线程中调用它的FFI函数是不是安全?【英文标题】:IsitsafetopassaJavaScriptcallbacktoanFFIfunctionwhichcallsitinanotherthread?将JavaScript回调传递给在另一个线程中调用它的FFI函数是否安全?【发布时间】:2016-1... 查看详情