いつもお世話になっております。m(_ _)m
どうしてもPythonからNimで作成したツールを使用する必要があり、また少し大きめの文字列をNimで作成したツールからPythonに渡さなければならず、色々調べたのですが自分ではわからなかったので質問させてください。
後述しているように他の方法を検討してみたのですがうまくいかず、現在はdllでやり取りできないかと考えております。
そこで以下のようにしてみました。(モデルです。)
fuga.nim
Nim
1proc hoge(): cstring {.exportc, dynlib.} = 2 result = "hoge"
dllファイル化
bash
1$ nim c --app:lib fuga.nim
fuga.py
Python
1from ctypes import cdll 2import ctypes 3 4dll = cdll.LoadLibrary('./fuga.dll') 5hoge = dll.hoge 6print(hoge()) # => 自分の環境では1802407936になりました。
しかし、コメントアウトに示すように、整数値が表示されてしまいました。
おそらく文字配列のアドレスか何かかと思い、Nim側でptr
とaddr
関数を使用し、Python側でc_buffer
を使用する、といったことを行ったのですがこれもうまくいきませんでした。
Nim
1proc hoge(st: var ptr cstring) {.exportc, dynlib.} = 2 var hoge = cast[cstring]("hoge") 3 st = hoge.addr
Python
1from ctypes import cdll, c_buffer 2import ctypes 3 4st = c_buffer(b"", 32) 5dll = cdll.LoadLibrary('./fuga.dll') 6hoge = dll.hoge 7hoge(st) 8print(st.value) # => b'X\xee\x1e\xb7Y' # 実行毎に変動しました
どうすればdllを介して文字列をやり取りできるのでしょうか?
ファイル等を介してやり取りするのではなく、dllを使用しなければならない理由は、実際のコードでは関数呼び出しを相当な回数行う必要があり、処理時間が膨大になってしまうと考えているからです。
始めはpexpect
を使用して子プロセスとしてやり取りすることを考えていたのですが、Windowsだとwinpexpect
を使用しなければならずさらに試してみてダメだったので断念しました。(subprocess
が使えないのはインタラクティブなやりとりが必要だからです。)
ダイナミックリンクライブラリ自体、必要に迫られて先ほど触り始めたのでほとんど理解していません。。
この分野に詳しい方、もしくは何か解決策の糸口となる方法をご存知の方がおりましたら、何卒よろしくお願いいたします。m(_ _)m
環境
- Python 3.6.4 :: Anaconda, Inc.
- Nim Compiler Version 0.18.0 [Windows: amd64]
- MINGW64_NT-10.0 **** 2.10.0(0.325/5/3) 2018-02-09 15:25 x86_64 Msys
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/11/15 12:56