スマートフォン用の表示で見る設計と実装の狭間で。この広告は、90日以上更新していないブログに表示しています。PythonうっかりCのライブラリが世の中リリースされてたりされてなかったりする訳ですけども、プロトタイプ的な何かを作ろうと思った時に、ヘタレはCで頑張ったり出来なかったりするのですね、主に僕とか。いや、Cが全然書けないって言うつもりは無いけど、漢の子ならゴリゴリ書けるだろJKとか言われても困る訳で。言う訳で、Pythonとか使っちゃうのです。実は僕、Pythonの事良く知らないんだけどもさ。Express上で使ってみますよ、と言う話。Studio経由でコンパイルする手順Python2.7がインストール済みで、PATHに通っているものとします。僕がダウンロードしたのは、Cython-0.13.zipと言うアーカイブ。アーカイブを展開して、そのディレクトリでインストールコマンドを実行します。installその後、binディレクトリに入っているcython.batをpython.exeがあるディレクトリにコピーします。Studioでプロジェクトを作ります。何か色々余計なモノをつけてくれようとするのだけど、全部拒否ってDLLを生成する空のプロジェクトにします。新しいフィルタとしてCythonを追加します。ここは、分かり易ければ名前は何でも良いです。次にプロジェクトのあるディレクトリをエクスプローラで開きCythonのHelloCython.pyxファイルを新規作成します。Cythonのデフォルトの挙動では、ファイル名と同じモジュールをエクスポートしようとします。Studioのデフォルトの挙動ではプロジェクト名と同じDLLを出力しようとします。両者にズレがあると余計な設定をする必要があるので、プロジェクト名と.pyxのファイル名は合わせておいて下さい。Studioのプロジェクトに、当該ファイルを取り込みます。最初の一回だけはこの謎のダイアログの後にウィザードが始まります。Studioを再起動しましょう。上からテキトーに値を入力していきます。最後に「ビルド規則の追加」ボタンを押します。ダイアログが表示されますので必要な項目を入力していきます。自分で入力する必要があるのは以下の項目です。Cythonコマンドラインの中では、半角スペースがプロジェクトのパスに含まれる可能性があるので、クオートします。ファイル拡張子はpyxだけ入れると前の部分は勝手に追加してくれます。出力は、Cythonの実行結果としてどんなファイルが出力されるのかなので、クオートしません。ファイル名であってパス名では無いのです。Studio上で開きチュートリアル的なコードを入力します。sin(x*x)そして、HelloCython.pyxを選択し、コンテキストメニューからコンパイルを選択します。Cythonの実行に成功すれば、HelloCython.cが生成されるので、これをプロジェクトに取り込みます。最後にCコンパイラ及びリンカの設定をしていきますが、プリプロセッサの_DEBUGフラグを立ててビルドすると、pyconfig.hの動作によって、python27_d.libが足りない等という事になるので、リリースビルドだけを行います。リリースビルドでもデバッグシンボルである.pdbファイルは生成されるので、恐らくきっと実用上は問題ない筈です。してもデバッグビルドをしたい人は、pythonのビルドからやって下さい。ディレクトリ」を編集します。Cythonでは、「Python.h」を参照しますので、pythonのインストールディレクトリにあるincludeディレクトリを指定します。空のプロジェクトで開始していますので、.cや.cpp等C系リソースを追加しないと、プロジェクトのプロパティに「C/C++」が出現しません。ここでは、C:\Python27\includeを指定しました。次に、プロジェクトのプロパティにおいて「リンカ」の「全般」を選択し、「出力ファイル」を編集します。ここは、最初から$(OutDir)\$(ProjectName).dllと入っていますが、$(OutDir)\$(ProjectName).pydに出力されるファイルの拡張子を「.pyd」に変更します。Windows版のPythonはモジュールの検索対象として「.dll」を使用せずに、「.pyd」を使用します。この様な仕様になっているのか、理解に苦しみますが、特に興味も無いので、ハイハイと従います。何か合理的な理由があるのでしょう。linuxやMacだと標準的な.soでOKなのにさ。ディレクトリ」を編集します。ここでは、C:\Python27\libsを指定しました。これでついにビルドできます。ソリューションのビルドを選択しビルドを実行します。ソリューションのReleaseディレクトリにビルドの実行結果が出力されます。このディレクトリにHelloCythonTest.pyを新規作成します。Pythonをインストールすると一緒にインストールされるIDLE等を使うと便利です。こんなコードを書いて実行するとCの関数をPythonから呼び出せる事が確認出来ます。fprint(f(3.1))これで、ある程度単純なCの関数ならば、簡単にPythonから呼出す事が出来るのが分りました。Pythonの関数をCython経由でCのライブラリにコールバック関数として関数ポインタを渡す話Cのライブラリを動作させる上で決して避けて通れない仕組みの一つが関数ポインタを引き渡してコールバックしてもらう事です。CとPythonを接続する上で、既存のCライブラリで要求するコールバック関数を出来る事ならばPythonで実装したいものです。Cythonではある程度のグルーコードを書くだけで、これを実現する事が出来ます。僕が知っているタイプのコールバック系のコードを二つばかし用意してみました。他にも何か色々ある様な気がしますが、直ぐに思いつくのはこれくらいって事で一つお願いします。*cfg);#endifその実装はこんな感じ。(callback)(a,b,cfg);}それに対して、Cythonではこういう風にコードを書きます。<void*>f)さっき作ったプロジェクトのpyxファイルを編集しています。globalを使う方がキャストが少ないので、僕としては好みです。Pythonの機能は良く分らないのですけども、globalと言うキーワードは使うのがためらわれる感じがします。呼出し側が好き勝手なポインタを設定出来るAPIと言うのは拡張性に優れている様な気がしないでもないですが、void*がそこらじゅうにとっ散らかる上にキャストを連発せざるをえないので、どうも安全性が気がかりです。うっかり不思議空間にポインタがすっ飛んでいったりしない様に気をつけないといけません。細かいCythonの文法についてはマニュアルを参照して下さい。Codeこれを動かすpythonのコードは例えば以下の様になります。a+bprint(simple_call(1,3,add))print(withcfg_call(3,5,add))以下の様に出力されますね。48簡単過ぎるせいなのか分らないですけども、Cythonのマニュアルには具体的なコードが見当たらず、少し苦労しました。良い方法を知っている方は教えて下さい。Cから構造体のポインタをCython経由でPythonから触れる様にラップして渡す話ある程度作りの良いCのライブラリではデータ構造をきちんと構造体として定義しています。その値をそのまま一々コピーしていたのではメモリが幾らあっても足りないので、構造体のポインタを引き渡す事を行います。CにおけるポインタをPythonの世界にそのまま持ってくる事は出来ません。そこで、Cythonでは構造体のポインタをクラスでラッピングしてPythonに引き渡します。具体的には、以下の様なCのコードがあったとします。7;(callback)(&c);}これをラップするCythonのコードは以下の様になります。pick_color(pick_color_proxy)Cython固有の構文を使っていますが、その詳細については、Cythonのドキュメントを確認して下さい。Typesこれを動かすPythonのコードは以下の様になります。print(c.red)pick_color_call(pick)以下の様に出力されますね。72これもまたやってみれば、どうという話では無いものの、Cythonのドキュメントにはサンプルが無くどうしたものか色々と試行錯誤しました。PyRex製Win32/MFCラッパで、けっこういろいろやってます。ありがとうございます。軽く見た感じ色々な使い方をしておりかなり参考になります。intポインタをPythonで配列の様に扱う。java.util.ServiceLoaderを使う。読者になる検索リンクはてなブログブログをはじめる週刊はてなブログはてなブログPro最新記事logback.groovyで設定記述しようとしたらアレな事になった件についてGradle-WrapperにHTTPとHTTPSのプロキシを設定して動かす。GitHubにGradleでリリース作業する。同一のGroupIdかつ同一バージョンで複数のArtifactIdを依存ライブラリとして指定する。月別アーカイブはてなブログをはじめよう!taichitaichiさんは、はてなブログを使っています。あなたもはてなブログをはじめてみませんか?はてなブログをはじめる(無料)はてなブログとは設計と実装の狭間で。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。