问题标签 [rust-bindgen]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
0 回答
233 浏览

enums - 使用 Rust 宏转换和拆分由 bindgen 生成的 C 样式枚举

我正在为现有的专有 C 库制作 Rust 绑定。该库定义了一个相当大的枚举,其中包含可能的状态错误代码,即:

库函数返回这些RET_CODE值。状态码开头STA_并不意味着失败;它们表示各种情况。错误代码以ERR_.

我的想法是将这个枚举分成两个 Rust 枚举,StatusCode并且ErrorCode,就像这样:

然后, Rust 包装器函数将返回std::result::Result<StatusCode, ErrorCode>. 但是,我不想手动定义那些 Rust 枚举,因为 C 库中的状态和错误代码可能会发生变化,而且我很可能会忘记更新 Rust 绑定。修改 C 库不是一种选择。

是否可以使用 Rust 宏(或其他东西)从单个 C API 枚举中生成这些 Rust 枚举?也可以重命名变体(即STA_SOME_CONDITION变为SomeCondition),但这显然可以由 bindgen 处理ParseCallbacks

0 投票
1 回答
898 浏览

windows - Rust Bindgen:在 Windows 上设置包含路径

我是 Windows 下 Rust 开发的新手。

我正在尝试在windows和libk4alinux 上绑定一个库.libk4a/usr/local/include/k4a/k4a.h/usr/local/lib/libk4a.so

我已经按照 bindgen 书的例子做了一个wrapper.hto pass to build.rs,这很简单:

这在 linux 下工作正常,build.rs设置为

在 Windows 上,dll 位于下方C:\Program Files\Azure Kinect SDK v1.3.0\sdk\windows-desktop\amd64\release\bin\,标题位于C:\Program Files\Azure Kinect SDK v1.3.0\sdk\include\k4a\k4a.h

虽然我可以自己运行 bindgen

如果它尝试在我的 build.rs 中添加包含路径,如前面的答案所示

我仍然收到错误说它找不到头文件:

我是否缺少向包含路径添加内容的地方?应该k4a/k4a.h在我的路上吗?还是我的配置中有错字?我不确定为什么它bindgen在命令行上与 raw 一起使用,但不是build.rs.

0 投票
0 回答
211 浏览

rust - 如何在 rust 结构中安全地包装 C 指针

我正在为 Rust 中的 C 库构建安全绑定,我开始面临一个奇怪的问题。

我创建了一个结构来拥有指向库返回的对象的不安全指针并安全地释放它们。

这就是我所拥有的:

只要我不在async通话之间共享它,它就可以正常工作。如果我在async函数中返回其中一个对象并在之后使用它,它将被损坏。如果我在一次操作中使用并释放它们,它们会按预期工作。我将如何实现Send这样Sync的结构,以便我可以在线程之间安全地共享它?

如果有人想检查完整的库代码,这里是链接

0 投票
2 回答
639 浏览

enums - 如何将由 bindgen 生成的 C 样式枚举转换为另一个枚举?

我在 Rust 中为 C 库和 Bindgen 生成的枚举创建绑定,例如:

我需要将这些转换为:

从该 C 库导入常量值时:

我想做类似的事情:

我该怎么办?

0 投票
0 回答
306 浏览

rust - 如何将 Bindgen 生成的静态全局变量转换为全局常量?

Bindgen 从static constC 风格的全局结构生成它:

我想安全地将它绑定到constRust 中的全局变量。

到目前为止我最好的尝试是

我收到以下编译错误:

我该怎么办?

0 投票
0 回答
203 浏览

c - 使用 Bindgen 在 Rust 中包装 C 风格的 `static const` 全局常量的解决方案是什么?

我正在为定义标准常量默认值列表的 C 库创建 Rust 绑定:

使用 Bindgen,static生成 Rust 变量:

但是static全局变量在 Rust 中使用起来非常不方便,必须将每个访问都封装在一个unsafe {}块中。特别是当您不需要可变性时。

我已经用 Rust 包装了结构和枚举:

现在,我正在寻找一种解决方案来rmw_qos_profile_sensor_data向我的 Rust 用户公开相同的预定义配置文件,例如 ,而无需在 Rust 中手动复制 C 值。

目前我正在用 Rust 复制 C 代码:

但这并不令人满意。当上游 C 库更新这些值时,用户会遇到不一致的行为和错误。

方便地包装这些全局常量的可能解决方案是什么?

理想的解决方案是:

  • 上游 C 库更改时自动更新值
  • 公开 globalconst以便编译器可以内联这些值
  • 如果不可能,公开全局不可变变量
  • 如果仍然不可能,至少不需要unsafe

我一直面临的问题是,由于static constC 结构存储在内存中,它们不能const轻易翻译成 a,这可能就是 Bindgen 使用static关键字翻译它的原因。

因此,我可以想象但不知道如何执行的可能性是:

  • 对 C 代码进行更智能的解析以生成 Rust 代码?
  • 使用某种形式的宏
  • 从前奏中的 C lib 的静态内存初始化?
  • 显式地从 C lib 的静态内存初始化?
  • 其他解决方案?
0 投票
1 回答
1147 浏览

c - 如何在 Rust 中正确包装 C 函数指针?

我有一个Foo带有函数指针的 C 结构。在我的 Rust 绑定中,我想允许用户设置这个函数指针,但我想避免用户不得不处理 FFI 类型。

foo.h

foo.c

我当前的解决方案是创建一个 Rust 结构Bar,它有一个指向 bindgen 生成的 C 结构的指针foo_sys::Foo,并且在其中我有一个 trait 对象 ( rust_cb),它是我想在 Rust API 中公开的实际回调。我将 C设置cb为指向 awrapped_cb并将internal指针设置为指向Bar,这样我就可以rust_cb从内部调用wrapped_cb

此代码有效,但抱怨访问未初始化的内存。当我使用 Valgrind 运行它时,我看到invalid reads了访问(*bar).rust_cb内部的点wrapped_cb。我不确定我做错了什么。

我查看了相关问题,这些问题似乎回答了我的问题,但解决了不同的问题:

这用于dlsym从 C 调用 Rust 回调。

这些描述了将闭包作为 C 函数指针传递的解决方案。

我想要实现的是拥有一个 Rust struct ( ),它有一个指向 C struct ( )Bar的成员变量,它本身有一个指向 Rust struct的成员变量。ptrFoovoid *internalBar

这个想法是在 Rust struct 中Bar为每个函数指针在 C struct中拥有一个 trait 对象和包装函数Foo。创建Bar对象时,我们执行以下操作:

  • 创建 CFoo并在Bar.
  • 指向Foo->callback包装器 Rust 函数。
  • 指向。Foo->internal_Bar

由于包装函数被传递了internal指针,我们能够获得一个指针Bar并调用相应的闭包(来自 trait obj)。

我能够将 Cvoid*指向我的 Rust 结构,并且我还能够从 Rust 回调(或闭包)中获取指向它的指针,这就是相关问题所要解决的问题。面临的问题可能与生命周期有关,因为其中一个值的寿命不够长,无法在回调中使用。

0 投票
4 回答
1150 浏览

rust - 如何在不实例化的情况下在 Rust 中获取结构字段的大小

我有一个包含字节数组的结构。这个结构实际上来自于 bindgen 产生的 FFI 绑定,它的大小是在 C 代码中使用宏定义的,即:

C代码:

生成的 FFI 绑定:

我想确保来自 Rust API 端的数据适合foo. 我也不想FOO_SIZE在我的 Rust API 中硬编码,因为它可能会发生变化。

我知道这可以通过首先实例化 struct 来完成,但话又说回来,这需要显式初始化foo,如果不知道它的大小,这似乎是不可能的。此外,这是我想避免的额外步骤。

是否有可能在不实例化结构的情况下以某种方式获得foo静态的大小?如果没有,最好的方法是什么?更改 C 代码不是一种选择。

0 投票
0 回答
291 浏览

rust - 有没有在我的 build.rs 中调试 CBindgen 使用的好方法?

我的 build.rs 脚本在我的 CI 管道 (Azure Pipelines) 中失败,但在本地运行它工作正常。我特别知道我无法生成我的 cbindgen 标头,但错误消息只是列出了它解析的文件,并没有真正说明它失败的原因。

构建.rs:

cbindgen.toml:

我在 generate_with_config().unwrap() 上失败了,错误消息是我正在尝试编译的 crate 列表,然后是一个典型的 unwrap() 堆栈,开头为:

对于每个依赖项都像这样继续,没有错误消息

0 投票
1 回答
455 浏览

rust - rust bindgen 中的链接失败

所以我有一个头库(.h 文件的目录),我需要在我的 rust 代码中使用它。为了让这个工作,我一直在寻找各种板条箱来帮助我实现这个,看起来 bindgen 是最有希望的选择。我遵循了 bindgen 的文档并创建了一个 wrapper.h 和一个 build.rs 文件。在 build.rs 文件中,我已将所有需要的函数列入白名单,文档中提到的链接参数指定为println! ("cargo:rustc-link-lib=C/complete path to my header files");. 但是在进行货物构建时会失败并出现以下错误:

我无法找到解决方案。非常感谢任何帮助或建议。