Rust programming language

C/C++ Rust Tech

【Rust】C++からRustを呼び出す方法

この記事でわかること

RustからC++を呼び出した後に、さらにC++からRustに何か通知したい場合があると思います。

本記事では、そのケースで、C++からRustのAPIを呼ぶ方法を説明します。

(下図のCallbackのところ)

RustからC++を呼び出す方法

こちらの方法は下記記事を参考にしてください。

Rust programming language
【Rust】RustからC++ を呼び出す方法

この記事でわかること Rustに移行したいけど、全部を移行することはできない場合、一部のC++コードを呼び出したいと考える方も多いでしょう。 特に、外部のライブラリを使用する場合は、Rustのライブラ ...

C++からRustを呼び出す方法

上記記事の続きから説明します。

1. Rust側の実装

C++の呼び出しに関しては、こちらを参考にしてください。

Rust側の実装はこちらです。


// cxx_example/src/main.rs
#[cxx::bridge]
mod ffi {

    extern "Rust" {
        fn callback();
    }

    unsafe extern "C++" {
        include!("cxx_example/src/hello.h");

        fn hello();
    }
}

fn callback() {
    println!("Callback");
}

fn main() {
    ffi::hello();
}

extern "Rust" {}

で括った関数をRustでは呼び出すことができます。

これを、呼び出したC++のhello()の中で呼び出します。

2. C++側の実装

cxx_example/src/hello.hcxx_example/src/hello.cppを次のように記述します。


// cxx_example/src/hello.h
#pragma once
#include "rust/cxx.h"

void hello();

// cxx_example/src/hello.cpp
#include "hello.h"
#include "cxx_example/src/main.rs.h"

void hello() { callback(); }

#include "cxx_example/src/main.rs.h"

をインクルードすることで、Rustで定義した

callback()

を呼び出すことができます。

main.rs.h自体は実装していませんが、コンパイルする過程で生成されるので、それをインクルードしています。

3. ビルド設定

Cargo.tomlbuild.rsを次のように記述します。


[package]
name = "cxx_example"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
cxx = "1.0"

[build-dependencies]
cxx-build = "1.0"

fn main() {
    cxx_build::bridge("src/main.rs")
        .file("src/hello.cpp")
        .flag_if_supported("-std=c++20")
        .compile("cxx-example");
    println!("cargo:rerun-if-changed=/src/*");
    println!("cargo:rerun-if-changed=/build.rs");
}

4. 実行


cargo run
// output: Callback

実行して「Callback」と出たら成功です。

終わりに

今回は、Rust→C++→Rustと呼び出す方法を説明しました。

全コードはこちらを参照してください。

-C/C++, Rust, Tech,
-, , ,