将python代码转换为共享对象

时间:2014-08-05 12:04:43

标签: python c cpython

我想从python模块准备一个共享对象(.so)。我遇到了Cython,它会a)首先将* .pyx模块转换为* .c代码,b)然后将这个* .c代码转换为共享对象(.so)。然后,Cython的所有示例都说明了如何将这个.so导入到python中。

但是,我有兴趣从C代码中读取这个共享对象。当我编写一个示例C代码来读取.so时,它会抛出一个错误,说明.pyx中实际存在的方法不存在于.so对象中。

我想知道 a)是否可以从不同的语言(如C)中读取Cython中的共享对象 b)并且,如果上述语句为True,我必须在代码中进行哪些更改,以便能够从C读取共享对象。

谢谢,

Python代码(保存为square_number.pyx)

def square_me(int x):
    return x * x

Cython的相应setup.py文件

from distutils.core import setup
from Cython.Build import cythonize

setup(
    ext_modules=cythonize("square_number.pyx"),
     )

用于将上述.pyx转换为.So(通过cython)

的命令行语句
python setup.py build_ext --inplace

这将在同一文件夹中创建一个square_number.so。现在,我将其重命名为libSquareNumber.so

用于阅读.so的C代码

#include<stdio.h>

int main(int argc,char *argv[])
{
    int result;

    result=square_me(2);

    printf("Sum of entered numbers = %d\n",result);

    return 0;
 }

当我尝试从上面的命令编译和构建可执行文件时,我收到错误

C代码编译:

gcc -L/home/USRNAME/work/cython-codes/squaring/ -Wall -o test so_reader_in_c.c -lSquareNumber

错误

so_reader_in_c.c: In function ‘main’:
so_reader_in_c.c:11:4: warning: implicit declaration of function ‘square_me’ [-    Wimplicit-function-declaration]
result=square_me(2);
^
/tmp/ccE5vIOH.o: In function `main':
so_reader_in_c.c:(.text+0x1a): undefined reference to `square_me'
collect2: error: ld returned 1 exit status

3 个答案:

答案 0 :(得分:2)

将square_number.pyx更改为:

cdef public int square_me(int x):
    return x * x

运行“setup.py”后,它将生成头文件“square_number.h”。 在主应用程序中包含它。见下文:

将“主要”功能更改为:

#include <Python.h>
#include "square_number.h"

int main()
{
    Py_Initialize();
    initsquare_number();
    printf("%d",square_me( 4 ) );
    Py_Finalize();
    return 0;
}

编译时请确保链接libpython.so和libsquare_number.so 您还需要通过给gcc提供-I标志来处理“Python.h”的包含目录搜索路径。

有关详细信息,请参阅:http://docs.cython.org/src/userguide/external_C_code.html

答案 1 :(得分:0)

我不记得这个细节了,我可能会在以后给出一个更详细的答案。然而,基础知识是Cython在导出C兼容的SO之前通过名称修改函数放置python函数。然后Python在导入Cython模块时理解同名的错误,因此可以调用正确的函数。

您需要做的是使用cython模块上的SO扫描库来资助实际调用的函数。要做到这一点尝试运行:

readelf my_cython_so.so

这将提供共享对象内容的转储,包括链接器使用的函数入口点和名称。然后,您可以使用这些名称来查找从代码中调用的正确函数。要在c代码中自动执行此操作,您可以使用libelf。

答案 2 :(得分:0)

将字节码转换为汇编不涉及C.它可能涉及由C调用的类,或以类似C的方式调用其他C类。但它仍然是字节码或汇编。你不能扭转从未有过的东西。使用objectdump -d -M。要概述这些类,那么如果你仍然需要,手动将这些类转换为C,那么请感谢我们让python为我们做到这一点。