C++ 与 Rust 接口 - 返回 CString 恐慌

2024-01-07

我正在尝试从 C++ 调用一些用 Rust 编写的函数。到目前为止,我已经相当成功,但我仍然有一个小问题CString运行时相关的恐慌。

功能hello应该接受一个输入字符串,将其与其他字符串连接起来并返回结果。

这是我的fun.rs:

use std::ffi::CString;

#[no_mangle]
pub extern "C" fn add(a: i32, b: i32) -> i32 {
    a + b
}

#[no_mangle]
pub extern "C" fn hello(cs: CString) -> CString {
    let slice = cs.to_str().unwrap();
    let mut s = "Hello, ".to_string();
    s = s + slice;

    CString::new(&s[..]).unwrap() // runtime error
    // CString::new(cs).unwrap()  // empty string if no borrow
    // cs                         // works if no borrow, but this is not what I meant
}

Here's main.cpp:

#include <iostream>
using namespace std;

extern "C" {
  int add(int a, int b);
  const char* hello(const char*x);
}

int main()
{
  int a, b;
  cin >> a >> b;
  cout << add(a,b) << ";" << hello("Pawel") << std::endl;
  return 0;
}

And makefile:

rust:
        rustc --crate-type=staticlib -C panic=abort fun.rs

cpp:
        g++ -c main.cpp

link:
        g++ main.o -L . libfun.a -o main -lpthread -ldl -lgcc_s -lc -lm -lrt -lutil

运行可执行文件的命令:

$ make rust
$ make cpp
$ make link
$ ./main
1 2

可执行输出:

1 2
thread '<unnamed>' panicked at 'index 18446744073709551615 out of range for slice of length 0', ../src/libcore/slice.rs:549
note: Run with `RUST_BACKTRACE=1` for a backtrace..

回溯:

stack backtrace:
   1:           0x435d4f - std::sys::backtrace::tracing::imp::write::h46e546df6e4e4fe6
   2:           0x44405b - std::panicking::default_hook::_$u7b$$u7b$closure$u7d$$u7d$::h077deeda8b799591
   3:           0x443c8f - std::panicking::default_hook::heb8b6fd640571a4f
   4:           0x4099fe - std::panicking::rust_panic_with_hook::hd7b83626099d3416
   5:           0x4442a1 - std::panicking::begin_panic::h941ea76fc945d925
   6:           0x40b74a - std::panicking::begin_panic_fmt::h30280d4dd3f149f5
   7:           0x44423e - rust_begin_unwind
   8:           0x451d8f - core::panicking::panic_fmt::h2d3cc8234dde51b4
   9:           0x452073 - core::slice::slice_index_len_fail::ha4faf37254d75f20
  10:           0x40e903 - std::ffi::c_str::CStr::to_str::ha9642252376bab15
  11:           0x4048e0 - hello
  12:           0x40476f - main
  13:     0x7f78ff688f44 - __libc_start_main
  14:           0x404678 - <unknown>
  15:                0x0 - <unknown>

有什么想法让 Rust 如此恐慌吗?


Rust's CString与C不兼容const char *。这是定义CString来自标准库:

pub struct CString {
    inner: Box<[u8]>,
}

This Box<[u8]>类型是一个胖指针,即包含指向切片项目的指针和切片长度的元组usize.

你应该做的是让你的 Rust 函数采用*const c_char争论然后调用CStr::from_ptr https://doc.rust-lang.org/stable/std/ffi/struct.CStr.html#method.from_ptr以该指针作为参数来获取CStr https://doc.rust-lang.org/stable/std/ffi/struct.CStr.html value.

至于返回值,存在一些问题:您的函数分配一个新字符串,然后返回指向它的指针。同样,你应该返回一个*const c_char,您可以通过调用来完成CString::into_raw https://doc.rust-lang.org/stable/std/ffi/struct.CString.html#method.into_raw在你的串联上CString价值。但为了避免内存泄漏,您还必须提供一个 Rust 函数,该函数将收回由hello并打电话CString::from_raw https://doc.rust-lang.org/stable/std/ffi/struct.CString.html#method.from_raw在其上,这将重新创建CString. The CString然后, 的析构函数将运行,释放内存。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ 与 Rust 接口 - 返回 CString 恐慌 的相关文章

随机推荐

  • 查明 Objective-C 类是否重写了方法 [重复]

    这个问题在这里已经有答案了 如何在运行时确定一个类是否重写了其超类的方法 例如 我想知道一个类是否有它自己的实现isEqual or hash 而不是依赖超类 您只需要获取方法列表 然后查找您想要的方法 import
  • 在 Flash 模式下寻找超出缓冲线的视频

    网络服务器模块ngx http mp4 module or mod h264 streaming允许 Flash 客户端使用 start 参数寻找超出下载缓冲区线的视频 例如 http server com path to video mp
  • 实体,处理大量记录(> 3500 万条)

    我们有一组相当大的相关表 每个表有超过 3500 万条相关记录 我需要创建几个 WCF 方法 它们使用一些参数 数据范围 类型代码等 查询数据库并返回相关结果集 从 10 到 10 000 条记录 该公司采用 EF 4 0 进行标准化 但对
  • 从 MS Access 2007 中删除 autoexec 宏

    我在 MS Access 2007 中创建了一个 autoexec 宏 但找不到它 我知道它在那里 因为它正在运行 但我找不到它来删除或修改 我可以看到我创建的其他宏 但没有看到自动执行宏 有人可以指出我正确的方向以找到它所在的位置 干杯
  • 如何获取最后滚动视图位置,scrollview

    我正在使用表格布局 其中有 100 个项目使其可滚动我在 ScrollView 中使用 Tablelayout 但我必须检测用户是否已滚动到最后一行 如果用户滚动到最后一个视图 则会向用户显示一条 Toast 消息 但是如何知道用户已滚动到
  • 配置 Silex 防火墙使用 api 密钥的正确方法

    我一直致力于制作一个接受 api 密钥的 api 并按照以下说明进行操作http symfony com doc current cookbook security api key authentication html http symf
  • 当前在 github 和 npmjs.org 上“退役”项目的最佳实践?

    我是 github 和 npm 上一个公共项目的维护者 当我创建该项目时 它比可用的替代方案更好地解决了我的特定需求 然而 社区已经赶上了并超越了我的解决方案 我什至不再使用我创建的工具 而且我对维护它不感兴趣 我为此更新了自述文件 但我仍
  • SQL Server 2005 报告服务 - 优点和缺点

    我正在使用 ASP NET 2 0 VS 2008 和 SQL Server 2005 开发一个 Web 应用程序 我想使用 SSRS 2005 来生成我需要为此 Web 应用程序构建的各种报告 我想说服团队 我们应该采用 SSRS 作为我
  • java.util.zip.ZipException:与 firebase 重复条目

    我正在使用 firebase 构建一个应用程序 但出现重复类错误 我已经检查了所有依赖项 但我无法弄清楚我在哪里有两个版本的 firebase 库 错误 任务 app transformClassesWithJarMergingForDeb
  • JavaScript 元组中的变量赋值

    在 Python 2 和 Python 3 等其他语言中 您可以定义元组变量并将值分配给元组变量 然后像这样检索它们的值 tuple Bob 24 name age tuple print name name evaluates to Bo
  • 如何自定义角度谷歌图表图例信息

    I have google chart line chart need to customize legend with some extra information Please refer this http plnkr co edit
  • MinGW C++ 使用向量退出值 127

    我在 C 中使用向量时遇到问题 我正在 Windows NetBeans 上使用 MinGW 以下代码 include
  • C使用malloc分配内存[重复]

    这个问题在这里已经有答案了 我不太明白 char string string malloc 1 if string NULL printf Couldn t able to allocate requested memory n else
  • 错误:用户“myuser”的密码验证失败

    如果我在 etc postgresql 9 4 main pg hba conf 中有一条记录特别信任我的特定用户 TYPE DATABASE USER ADDRESS METHOD local all myuser trust 因为我在
  • 你能在 Java 中运行真正的 ping 吗?

    过去几周我做了相当多的研究 试图创建一个连接诊断工具 我不想只是检查连接是否可用 而是诊断是否存在抖动 数据包丢失等 到目前为止 Java 似乎不支持真正的 ICMP 请求 并且有一些解决方法 但没有一个能够实现我想要做的事情 有谁知道是否
  • 基本的 javascript 所见即所得编辑器

    我可以获得有关如何使用文本区域制作所见即所得编辑器的解释吗 我需要它做的就是解析基本的 html 标签 如粗体 斜体 下划线等 它不需要任何插入它的按钮 我只想在解析的文本区域标签内有一个默认文本html Example
  • 我怎样才能有启用/禁用按钮附近的条目的功能?

    import tkinter as tk class App tk Frame def init self super init self pack self buttons self entries for n row in range
  • WiX 包含与片段

    WiX 包括 wxi文件 和 WiX 片段 wxs文件 每个的用例是什么 Which should被使用 为什么 文件扩展名只是为了方便 文件的内容才是真正重要的 这种区别使得管理实际安装 wxs 文件 和创建安装所需的属性 wxi 文件
  • 使用 PHP 将图像中的一种颜色替换为另一种颜色

    是的 我知道 stackoverflow 上有相关的问题 但它们并不完全符合我的需要 我正在尝试用另一种颜色替换图像的颜色 在下面的代码中 我将 255 0 255 替换为 0 192 239 下面的代码可以工作 但不能完美地替换粉色 25
  • C++ 与 Rust 接口 - 返回 CString 恐慌

    我正在尝试从 C 调用一些用 Rust 编写的函数 到目前为止 我已经相当成功 但我仍然有一个小问题CString运行时相关的恐慌 功能hello应该接受一个输入字符串 将其与其他字符串连接起来并返回结果 这是我的fun rs use st