はじめに
RustからC/C++を呼び出す記事はたくさん見つかったが、C/C++からRustを呼び出す記事が全然見つからなかったので試したときの備忘録
環境
-
- Rust 1.55.0
- MSVC V19.29.30038.1 for x64
RustでDLLライブラリを作る
DLLを作る
#![crate_type = "cdylib"]
#[no_mangle]
pub extern "C" fn greeting() {
println!("Hello, {}", "Rust");
}
#[no_mangle]
pub extern "C" fn rust_add(x: i32, y: i32) -> i32 { x + y }
#![crate_type = “cdylib”]でコンパイルするとダイナミックCリンクライブラリが出力されるようになる。#![crate_type = “dylib”]にすると、ダイナミックなRustリンクライブラリができる。が、どちらでも実行できたのでよくわからず。
#[no_mangle]でコンパイル時にマングリングしないように指定する。
下記のコマンドでコンパイルする
$ rustc sample.rs
何も出なければOK
コンパイルするとディレクトリは下記のようになる。
.
├── sample.dll
├── sample.dll.exp
├── sample.dll.lib
├── sample.pdb
└── sample.rs
これでDLLの作成は完了
Cヘッダーファイルを作る
void greeting();
int rust_add(int, int);
追加した関数は2つだけなので上記の2行だけでOK
DLLを呼び出すCを作る
#include <stdio.h>
#include "sample.h"
int main(int argc, char** argv) {
greeting();
printf("result: %d\n", rust_add(3, 9));
return 0;
}
ヘッダー読み込んで、使うだけ
コンパイルする
$ cl main.c sample.dll.lib
Microsoft(R) C/C++ Optimizing Compiler Version 19.29.30038.1 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
main.c
Microsoft (R) Incremental Linker Version 14.29.30038.1
Copyright (C) Microsoft Corporation. All rights reserved.
/out:main.exe
main.obj
sample.dll.lib
sample.dll.libじゃないとコンパイルが通らない。理由は不明。sample.dllにすると「ファイルが壊れています」とか言われてコンパイルできない。
MSVCコンパイラは64ビットを使わないとコンパイルができない。Visual Studioをインストールしたらついてくる「x64 Native Tools Command Prompt for VS 2019」を使えばOK
Rustコンパイラがデフォルトで64bitでコンパイルするから?
コンパイル後のディレクトリの中身は下記のようになる
.
├── main.c
├── main.exe
├── main.obj
├── sample.dll
├── sample.dll.exp
├── sample.dll.lib
├── sample.h
├── sample.pdb
└── sample.rs
実行してみる
$ main
Hello, Rust
result: 12
できた