web-dev-qa-db-ja.com

PythonでC関数を呼び出す

Cで書いた関数がたくさんあるので、これらの関数にアクセスできるようにPythonで書いたコードが欲しいです。

私はここで同様の問題に対処するいくつかの質問を読みました(たとえば、 here および here )が、どのアプローチをとる必要があるかについて混乱しています。

1つの質問はctypesを推奨し、別の質問はcythonを推奨します。私は両方のドキュメンテーションを少し読みましたが、どちらが私にとってうまくいくかについては完全に不明です。

基本的に、いくつかの2次元FFTを実行するためのコードをpythonコードで記述しました。Cコードでその結果を確認し、さまざまなC関数で処理できるようにしたいと思います。書かれています。CからPythonを呼び出すのが簡単なのか、その逆の場合かはわかりません。

30
Kitchi

私がよく理解していれば、c => pythonまたはlike python => c。のように対話することを好みません。その場合、Cython。これは、多くの種類の操作、特に、あなたの場合、Python Cから作成された関数を呼び出す.

仕組みは次のとおりです( public api ):

次の例では、Pythonクラス(selfはそのインスタンス))があり、このクラスにはメソッド(名前method)があると仮定していますこのクラスを呼び出して、Cの結果(ここではdouble)を処理します。この関数は、Cython extensionは、この呼び出しを行うのに役立ちます。

cdef public api double cy_call_func_double(object self, char* method, bint *error):
    if (hasattr(self, method)):
        error[0] = 0
        return getattr(self, method)();
    else:
        error[0] = 1

C側では、次のように呼び出しを実行できます。

PyObject *py_obj = ....
...
if (py_obj) {
    int error;
    double result;
    result = cy_call_func_double(py_obj, (char*)"initSimulation", &error);
    cout << "Do something with the result : " << result << endl;
}

PyObject は、Python/C APIが提供するstructです。py_obj(通常のpython objectをキャストすることにより、次のようなcython拡張で:<PyObject *>my_python_object)、最終的にinitSimulationメソッドを呼び出して、結果に対して何かを行うことができます。 (ここではdoubleですが、Cythonは vectorssets、... を簡単に処理できます)

さて、Cythonを使用して何も書いたことがない場合、私が書いたことは混乱を招く可能性があることは承知していますが、マージ

一方、このアプローチは、アルゴリズムの複雑さに応じて、PythonコードをCに再コーディングするよりも時間がかかる場合があります。Cythonの学習に時間をかけることは、この種のニーズを頻繁に抱えるには...

これが少なくとも参考になることを願っています...

10

ctypesラッパーを記述して、Python)からCを呼び出す必要があります。 ctypesは、C関数をpythonから呼び出し可能にするためのものです。

  1. 使用するC関数を作成します。 (おそらくこれをすでに行っているでしょう)
  2. これらの機能用に共有オブジェクト(Linux、OS Xなどの場合は.so)または動的にロードされたライブラリ(Windowsの場合は.dll)を作成します。 (おそらく、あなたもすでにこれをしました)
  3. Ctypesラッパーを記述します(見た目より簡単です そのためのハウツーを書きました
  4. Pythonでそのラッパーから関数を呼び出します。 (これは、他のpython関数)を呼び出すのと同じくらい簡単です。
55
Florian Rhiem

さて、ここでは、以下の2つを参照しています。

  1. From python(pythonの拡張)内でc関数を呼び出す方法
  2. Cプログラム(Pythonの埋め込み)からpython function/scriptを呼び出す方法

#2の場合 'Embedding Python'

以下のコードセグメントを使用できます。

#include "python.h"

int main(int argc, char *argv[]) {   
Py_SetProgramName(argv[0]);  /* optional but recommended */   
Py_Initialize();   
PyRun_SimpleString("from time import time,ctime\n"
    "print 'Today is',ctime(time())\n");
/*Or if you want to run python file within from the C code*/       
//pyRun_SimpleFile("Filename");    
Py_Finalize();   
return 0; }

#1の場合 'Extending Python'次に、Ctypesを使用することをお勧めします(ただし、Pythonのすべてのバリアントで移植可能)。

ctypesインポートから*

libc = cdll.msvcrt

print libc.time(なし)

1438069008

printf = libc.printf

printf( "Hello、%s\n"、 "World!")

こんにちは世界! 14

printf( "%d bottles of beer\n"、42)

42本のビール19

詳細なガイドについては、 私のブログ記事 を参照してください。

4
Jadav Bheda

PythonからCを呼び出す方が簡単です。あなたのシナリオは奇妙に聞こえます-通常、人々はほとんどのコードをpythonで記述します。コード?

2
xuanji