rustã§Cã§æ¸ããé¢æ°ãå¼ã¶ / Cããrustã§æ¸ããé¢æ°ãå¼ã¶
rustããCã®é¢æ°ãå¼ã¶æ¹æ³ï¼ãããã¯ï¼ãã®éï¼ã¯å ¬å¼ã®ããã¥ã¡ã³ã (https://doc.rust-lang.org/book/ffi.html)ã«æ¸ãã¦ããã®ã§ãããèªãã°ããã㧠ããï¼èªåã§æ¸ããCã®é¢æ°ãå¼ã¶æ¹æ³ã«ã¤ãã¦ç´æ¥ã¯æ¸ãã¦ãªãã®ã§ããã«ç°¡åã« ã¾ã¨ãã¦ã¿ã¾ãï¼
rustã§Cã§æ¸ããé¢æ°ãå¼ã¶
以ä¸ã®Cã§æ¸ããé¢æ°ãrustããå¼ã¶ãã¨ãèãã¾ãï¼
foo.c
#include<stdio.h> void foo(){ printf("foo!!\n"); }
rustãã以ä¸ã®ããã«ãã¦é¢æ°ã®å¼ã³åºãããããªãã¾ãï¼
main.rs
#[link(name="foo", kind="static")] extern{ fn foo(); } fn main() { unsafe {foo();}; }
#[link(name="foo", kind="static")]
ã¨ããã¨ãªã³ã«ãlibfoo.a
ããªã³ã¯ãã¦ã
ããããã«ãªãã¾ãï¼ã¾ãå¼ã³åºãCã®é¢æ°ã¯unsafe
ã§å²ãå¿
è¦ãããã¾ãï¼
ããã§ï¼å®éã«ããã°ã©ã ãã³ã³ãã¤ã«ããæ¹æ³ã§ããï¼
1. rustcã§ç´æ¥ãªã³ã¯ãã
ã¾ãfoo.cããã¢ã¼ã«ã¤ããä½æãã¾ãï¼
$ gcc -o foo.c
$ ar rcs libfoo.a foo.c
ããããï¼rustc
ã®-L
ãã©ã°ã§ã©ã¤ãã©ãªãç½®ãã¦ããå ´æãæå®ãã¦ãããã°ã³
ã³ãã¤ã«ã§ãã¾ãï¼ä»åã¯å
¨ã¦åããã£ã¬ã¯ããªã«ããã¨ãã¦ãã¾ãï¼
$ rustc -L. main.rs
$ ./main
foo!!
2. Cargoã§Cã®ã½ã¼ã¹ãä¸ç·ã«ãã«ããã
å®éã«ã¯rustc
ãç´æ¥å¼ã¶äººã¯ã»ã¨ãã©ããªãã¨æãã¾ãï¼
http://doc.crates.io/build-script.html ã«æ¸ãã¦ããéãï¼build.rsã¨ãããã¡ã¤
ã«ã«ãã«ãå¦çãæ¸ãã°cargoã使ã£ã¦Cã®ããã°ã©ã ãã³ã³ãã¤ã«ãããã¨ãã§ãã¾
ãï¼
ãã«ãå¦çãæ¸ãæ¹æ³ã¯ããã¤ãããã¾ããï¼ https://github.com/alexcrichton/gcc-rs ãå©ç¨ããã®ãç°¡åã ã¨æãã¾ã. gcc-rsã¨ããååã§ããwindowsãªãMSVCãå®è¡ãã¦ããããããã§ãï¼ãã èªåã windowsç°å¢ã§è©¦ãããã¨ã¯ãªãã§ãï¼
å ·ä½çã«ã¯ï¼ä»¥ä¸ã®ãããªãã©ã«ãæ§æã«ãã¾ãï¼
Cargo.toml build.rs src/ |----- main.rs |----- c |------- foo.c
ããã§ï¼Cargo.tomlã«ä»¥ä¸ã®ããã«è¨è¿°ãã¾ãï¼
[package] links = "foo" build = "build.rs" [dependencies] libc = "0.2.0" [build-dependencies] gcc = "0.3"
ã¾ãï¼build.rsã«ã¯ä»¥ä¸ã®ããã«è¨è¿°ãã¾ãï¼
extern crate gcc; fn main(){ gcc::Config::new() .file("src/c/foo.c") .include("src") .compile("libfoo.a"); }
ããã§ï¼cargo build
ã¨ããã°åæã«libfoo.a
ãã³ã³ãã¤ã«ããã¦ï¼ããã«
æ¬ä½ã®ããã°ã©ã ãã³ã³ãã¤ã«&ãªã³ã¯ããã¾ãï¼ãã¡ããï¼Cã®ã³ã¼ããä¿®æ£
ããã°cargo build
ã§èªåã§åã³ã³ãã¤ã«ãã¦ããã¾ãï¼
Cããrustã§æ¸ããé¢æ°ãå¼ã¶æ¹æ³
以ä¸ã®rustã®é¢æ°ãCã§å¼ã¶ãã¨ãèãã¾ãï¼
foo.rs
#[no_mangle] pub extern fn foo(){ println!("foo"); }
ããã§ï¼extern
ãã¤ãã¦é¢æ°ãCã®å¼ã³åºãè¦ç´ã«å¾ãããã«ãã¾ãï¼ã¾ãï¼
#[no_mangle]
ã§ãã³ã°ãªã³ã°ãããªãããã«ãã¦ãã¾ãï¼
å¼ã³åºãå ã®Cã®é¢æ°ã¯ä»¥ä¸ã®éãã§ãï¼
main.c
#include <stdio.h> void foo(void); int main(){ foo(); }
以ä¸ã®ããã«ããã°ï¼ããã°ã©ã ãã³ã³ãã¤ã«ã§ãã¾ãï¼
$ rustc --crate_type="dylib" foo.rs $ gcc -o main -L. -lfoo main.c $ ./main
staticã«ãªã³ã¯ããå ´åã¯ä»¥ä¸ã®ããã«ãã¾ãï¼
$ rustc --crate_type="staticlib" foo.rs $ gcc -o main main.c libfoo.a $ ./main
ã¨ãããã¨ã§rustããCã®é¢æ°ãå¼ã¶æ¹æ³ï¼or ãã®éï¼ã«ã¤ãã¦ç°¡åã«æ¸ãã¾ããï¼ å®éã«ã¯å¼æ°ãã©ããããã¨ãããããåé¡ãããã¾ããï¼å ¬å¼ã®ããã¥ã¡ã³ãã« æ¸ãã¦ããã¨æãã®ã§ãã¡ããåç §ãã¦ã¿ã¦ãã ããï¼ã¨ãããèªåãæ¸ããã»ã©ã¾ã 詳ãããªãã§ãã.. ã¨ããããä½ãæ¢ã«ããã©ã¤ãã©ãªã®é¢æ°ãå¼ã³ããã¨ããå ´ åã¯libcpuidãèªã¶ä¾ï¼http://siciarz.net/ffi-rust-writing-bindings-libcpuid/) ãåããããããªã¨æãã¾ããï¼