3

ある程度の進歩があったので、タイトルを変更し、新しい問題を説明する2回目の編集を行いました。Edit1を無視することを選択できます

私はCコードからPythonコードを実行しようとしています。そして、この目的のために、私はCythonを使用しています。

私のシステムのセマンティクスは、ファイルで定義されたC関数(ソースにアクセス可能)を呼び出すバイナリ(ソースにアクセスできない)があり、この関数内でPython関数を呼び出し、処理を実行して戻る必要があるというものです。結果をバイナリに変換します。

この目的を達成するために、私が遭遇した2つのアプローチがあります。

  1. http://docs.python.org/release/2.5.2/ext/callingPython.html ===>このアプローチでは、Pythonコールバック関数をC側に渡して、必要に応じてコールバックが呼び出されるようにすることをお勧めしますが、バイナリのソース(システム全体を実行するために使用される)にアクセスできないため、これは機能しません

  2. https://stackoverflow.com/a/5721123/1126425 ==>このアプローチを試しましたが、cython関数が呼び出されると、次のエラーが発生します:プログラム受信信号SIGSEGV、セグメンテーション違反。[スレッド0xb47deb70(LWP 2065)への切り替え] /usr/lib/libpython2.6.so.1.0からのPySys_GetObject()の0x007fd38a

  3. http://www.linuxjournal.com/article/8497?page=0,0 ==>これは実際にはcythonの機能の基礎ですが、ここで説明されている例を使用すると、2と同様のエラーが発生します。

これらのエラーを解決する方法がわかりません。どんな助けでも大歓迎です。

ありがとう!!

Edit1: これは状況を反映した簡単なシナリオです:


external.c

#include <external.h>

int callback(int param1,int param2)//Function that the binary calls
{
    /*SomeTasks*/
    cython_func();//Function defined in the following .pyx file
    /*SomeTasks*/
}

cython_file.pyx

cdef void cython_function():
    print "Do Nothing!"

cythonによって作成された共有ライブラリファイルを上記のCコードをコンパイルして生成されたライブラリにリンクしているので、そのライブラリはバイナリによって使用されます...

Edit2: Py_Initialize();を追加すると、セグメンテーション違反がなくなります。cython_function()を呼び出す前。しかし今、私は未定義のシンボルエラーを次のように受け取っています:シンボルルックアップエラー:lib_c_code.so:未定義のシンボル:cython_function

ここで、lib_c_code.soは、上記のexternal.cファイルから作成された共有ライブラリです。cythonコンパイラによって作成された.hファイルをexternal.cに含めようとしましたが、それでもうまくいきませんでした。lib_c_code.soをコンパイルする方法は次のとおりです。

gcc -shared -dynlib -lm -W1 -o lib_c_code.so $(OBJDIR)/*.o -lc -lm -lpy_code

libpy_code.soは、cython_file.pyxファイルから次のように作成された共有オブジェクトファイルです。

cython cython_file.pyx -o cython_file.c
gcc $(IFLAGS) -I/usr/include/python2.6 -fPIC -shared cython_file.c -lpython2.6 -lm -o libpy_code.so

また、次のようにすると、lib_c_code.soファイルにシンボルcython_functionが表示されます。nm-g lib_c_code.so ..何かアイデアはありますか?

4

1 に答える 1

0

ここで、関数ポインターを渡すことができるコールバック登録関数があると推測する必要があります。その場合、C ファイルを無視して、Cython コードで直接 cdef 関数を定義し、それをコールバック登録関数で渡すことができます。with gilその中の Python オブジェクトを操作する場合に使用します。

cdef extern from "external.h":
    ctypedef int (*Cb_Func)(int param1, int param2)
    void register_callback(Cb_Func func)

cdef int my_callback(int param1,int param2) with gil:
    <implementation>

register_callback(my_callback)

これは、Cython のユーザー マニュアルでも説明されています: http://docs.cython.org/src/userguide/external_C_code.html

于 2013-12-29T09:25:02.140 に答える