ページ

2015-06-07

RustでDLLを作る

期待通りの方法で作れた。ちなみに:
c:\>rustc --version
rustc 1.2.0-nightly (613e57b44 2015-06-01) (built 2015-06-02)
今回のは特にfeature使ってないから1.0でいけるかな?

DLLの作り方

まずプロジェクトを作る。
cargo new rustdlltest

Cargo.tomlを書き換えて、[lib]を作る。詳しくはhttp://doc.crates.io/manifest.htmlを参照。
[package]
name = "rustdlltest"
version = "0.1.0"
authors = ["user <user@example.com>"]
# See http://doc.crates.io/manifest.html
[lib]
name = "foo"
path = "src/lib.rs"
crate-type = ["dylib"]
view raw Cargo.toml hosted with ❤ by GitHub

lib.rsに、no_mangleとextern "C"をつけて、関数を記述する。
#[no_mangle]
pub extern "C" fn hello(count: i32) -> bool {
if count < 0 {
println!("A negative count is not supported.");
return false;
}
for i in 0..count {
println!("Hello, World: {}", i);
}
return true;
}
view raw lib.rs hosted with ❤ by GitHub

詳しくは、Rust bookの「Foreign Function Interface」を参照。

あとは、
cargo build

cargo build --release
で、target\debugあるいはtarget\releaseにfoo.dllができている。

Dependency Walkerで見てみると、いろいろな関数がexportされているが、その中で指定したhelloがexportされていることがわかる。


呼んでみる

楽なのでC#から呼んでみるには、こんな感じ。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace RustLibSample {
static class NativeMethods {
[DllImport("foo.dll", EntryPoint = "hello")]
public static extern bool Hello(int i);
}
class Program {
static void Main(string[] args) {
var r1 = NativeMethods.Hello(-1);
System.Console.WriteLine("Result for -1: {0}", r1);
var r2 = NativeMethods.Hello(3);
System.Console.WriteLine("Result for 3: {0}", r2);
}
}
}
view raw Program.cs hosted with ❤ by GitHub


結果はこう:
>RustLibSample.exe
A negative count is not supported.
Result for -1: False
Hello, World: 0
Hello, World: 1
Hello, World: 2
Result for 3: True

問題ない。boolってなによと思ってintにしてみたら、0と1らしい。

0 件のコメント:

コメントを投稿