我正在try 从CPP链接到Rust,然后从Rust程序链接回原始的CPP程序.

(这可能是XY的问题,所以我想做的是有一个用CPP加载模块写的游戏,用铁 rust 写的.所以我认为CPP将加载Ruust代码,然后注册物品等Ruust将调用CPP游戏中的函数.)

但现在我只是使用一个快速测试环境:

CPP文件:

//main.cpp
#include "rust.h"
#include "main.h"
#include <stdio.h>

int main() {
        hello();
        print(100, 1.6, true);
        return 0;
}

void cpp() {
        printf("hello from cpp");
}

// main.h
void cpp();
// rust.h
// generated with cbindgen
#include <cstdarg>
#include <cstdint>
#include <cstdlib>
#include <ostream>
#include <new>

extern "C" {

void hello();

void print(int32_t a, float b, bool c);

} // extern "C"


铁 rust 文件:

// lib.rs
mod cpp;

#[no_mangle]
pub extern fn hello() {
    println!("hello from rust");
}

#[no_mangle]
pub extern fn print(a: i32, b: f32, c: bool) {
    println!("int: {}, float: {}, bool: {}", a, b, c);
    unsafe { cpp::cpp(); }
}
// cpp.rs
/* automatically generated by rust-bindgen 0.65.1 */

extern "C" {
    pub fn cpp();
}

然后,我使用 crate 类型dylib编译了Rust,因此它输出了一个.so文件. 要编译我使用的cpp(rust程序的名称是external):

g++ -L ./external/target/debug/ -Wall main.cpp -l external

消息中有哪些错误:

/usr/bin/ld: ./external/target/debug//libexternal.so: undefined reference to `cpp'
collect2: error: ld returned 1 exit status

如果我在Rust程序中删除对cpp的引用,那么流就是cpp-&rust,一切都编译得很好.只是当提到cpp的词Rust 时,它才会流露出来:cpp-&gt;rust-&gt;

希望这是足够的信息:)


推荐答案

C++与铁 rust 一样,默认情况下它是导出的符号,为了避免它,你必须声明cpp()才能使用带有extern "C"的C ABI:


extern "C" void cpp() {
    printf("hello from cpp");
}

并且在头部main.h中也是如此.

Rust相关问答推荐

默认特征实现中的生命周期问题

你是如何在铁 rust 一侧的金牛座获得应用程序版本的?

`Pin`有没有不涉及不安全代码的目的?

从未排序的链表中删除重复项的铁 rust 代码在ELSE分支的低级上做了什么?

rust中的库插件管理器,现在是否可行?

Rust 中什么时候可以返回函数生成的字符串切片&str?

根据掩码将 simd 通道设置为 0 的惯用方法?

中文优化标题:跳出特定循环并返回一个值

Rust: 目标成员属于哪个"目标家族"的列表是否存在?

全面的 Rust Ch.16.2 - 使用捕获和 const 表达式的 struct 模式匹配

为什么 `tokio::join!` 宏不需要 Rust 中的 `await` 关键字?

使用自定义 struct 收集 Vec

判断对象是 PyDatetime 还是 Pydate 的实例?

改变不实现克隆的 dioxus UseState struct

Rust 内联 asm 中的向量寄存器:不能将 `Simd` 类型的值用于内联汇编

将数据序列化为 struct 模型,其中两个字段的数据是根据 struct 中的其他字段计算的

您如何使用枚举反序列化字符串,其中任何其他值反序列化为新类型变体同时保留字符串?

使用 rust-sqlx/tokio 时如何取消长时间运行的查询

如何从 many0 传播 Nom 失败上下文?

为什么这里需要类型注解?