d.sunnyone.org
sunnyone.org

ページ

2015-05-17

「RustからPythonを呼び出す」資料と補足

Rust 1.0 Release記念祝賀LT会 お疲れ様でした。そして1.0.0リリースおめでとうございます。今回は、その祝賀会で「RustからPythonを呼び出す」という話をしたので、その補足エントリです(資料は最下部に配置)。

rust-cpythonの使い方

RustからPythonを呼び出すには、rust-cpython crate が使えます。使い方は、githubに書いてあるとおりですが、以下のような感じで簡単に使えます(恐らく非Windows/x64 or Windows/x86,x64なら:資料参照)(2015/5/27追記:下部追記参照)

$ cargo new newapp
$ cd newapp

(Cargo.tomlを編集)
[dependencies.cpython]
version = "*"

(src/main.rsを作成)
extern crate cpython;

use cpython::{PythonObject, Python};

fn main() {
    let gil_guard = Python::acquire_gil();
    let py = gil_guard.python();
    let sys = py.import("sys").unwrap();
    let version = sys.get("version").unwrap().extract::().unwrap();
    println!("Hello Python {}", version);
}

$ cargo run

作りたかったもの

なぜこのような話になったかというと、DLLを作成することで拡張できるアプリケーションがあるのですが、その拡張する内容自体、LLでちょいちょい変えていきたいので、LLとつなぐブリッジとなるDLLを作りたかった(作りたい)のです。Pythonなのは、アプリ埋め込みがしやすく、統計処理が得意なライブラリを持っているから。あと、coroutineが使いたいので、Python 3.4以降が使いたいです(ここはRustでもまだできていないところですが、python3-sysがあるので、どっか切り替えればなんとかなるんじゃないかと思っているところ)

考えた言語たち

Rustを使いたいからというよりも、Rustが向いているのではと思ったからです。以下、考えた言語たち。

C#

今回はWindowsの世界だとわかりきっているので、私的にはC#で書けると一番楽です。しかし、C#のDLLはmanaged (CLRで動作する) DLLなので、普通のC関数として呼び出すことはできません。一応、その向きのために「Unmanaged Exports」というのがあるようですが、コンパイルできませんでした。多分「Can't create unmanaged dll using C# and Robert Giesecke's Unmanaged Exports tool」という記事にある問題だと思うのですが、試してません。動いても動かすにはCLRがついてくるはずなので、フットプリントが大きくなり、単なるPythonブリッジにはちょっと大きいという点が気になります。

C

いろいろなもののベースになっているはずなので、Cに限った話ではないのですが、PythonのC APIは親切に提供されているので、Cで書くのも悪くないと思います。ないがしろになりがちそうなC拡張のドキュメントがしっかり書かれていて、和訳もあるという親切な環境です。悪くないといえば悪くないのですが、リソース管理系の話だとか、objectiveな操作が書きにくいとか、ヘッダファイルが別で冗長とか、いろいろあるので、他にベターなものがあれば避けたいなと。

D

Win32 DLLs in Dという話も書いてあるし、これは結構ありかなと思っています。pydというPython bindingもあるみたいです。CPython 2.6+とあるので、2系しか考えてない気がしますが、Python 3系いけるかどうか。

ただ、GCがついてくるので、そのへん意識しないといけないですね。

Free Pascal (Object Pascal)

どこかでこれでDLLを書いてる例を見かけて、意外とありなのかなと思ったりしたりしました。Python4DelphiというPythonバインディングもあるようです。今からPascal覚えるのかーというところですね。

Rust

ここでRustを思い出して、よさそうだなと。#![create_type = "dylib"]と#[no_mangle]でDLLは作れそうだし、GCがないのでランタイムのオーバーヘッドも小さそうだし。そしてrust-cpythonを動かしてみたら、動いた ← 昼間ココ というわけです。

Pythonそのもの

呼び出そうと思っているのはPythonそのものなので、DLLがPythonで書けるとベターです。できないと思っていたのですが、Cythonを使うのはどうという話があり、こっちのほうがいいかも? ← 今ココ です。Pythonではないけど、専用のサポートがあるし、読む人もなじみやすそうですね。

とこんなかんじですが、他にもおすすめがあれば教えてください。

資料

ともあれ、資料はこちらになります。



. o O (もうちょっとうまいこと話せたらよかったのだけど、スタートがうまくしゃべれなかったせいでぐだぐだになってしまった...)

[2015/5/27 追記]
資料にあるLinux/x86でビルドできない罠ですが、Linux/x86対応をpull request出したらマージされたので、Linux/x86でもgitのmasterはビルドできるようになりました。Cargo.tomlもgitのほうを向ければビルドできるようになると思います。


0 件のコメント:

コメントを投稿