未定义的符号(链接.so C和Cython代码)

时间:2012-07-03 22:28:26

标签: cython

由于我取得了一些进展,我更改了标题并进行了第二次编辑,描述了我的新问题。您可以选择忽略Edit1

我一直在尝试从C代码运行python代码。为此我一直在使用Cython。

我的系统的语义是这样的,有一个二进制(我无法访问的源)调用文件中定义的C函数(源是可访问的),在这个函数中我需要调用python函数,做一些处理并将结果返回到二进制文件。

为实现这一目的,我遇到了两种方法:

  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的错​​误。

  4. 我不知道如何解决这些错误。任何帮助将不胜感激。

    谢谢!

    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文件创建的共享库。我试过在external.c中包含cython编译器创建的.h文件,但它仍然无法解决..这就是我编译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 .. 有什么想法吗?

1 个答案:

答案 0 :(得分:0)

我必须在这里猜测,有一个回调注册函数,你可以传递函数指针,在这种情况下你可以简单地放弃C文件并直接在你的Cython代码中定义一个cdef函数,并通过回调传递它注册功能。如果您操作其中的任何Python对象,请使用with gil

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