Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将python代码转换为共享对象_Python_C_Cpython - Fatal编程技术网

将python代码转换为共享对象

将python代码转换为共享对象,python,c,cpython,Python,C,Cpython,我想从python模块中准备一个共享对象(.so)。我遇到了Cython,它将a)首先将*.pyx模块转换为*.c代码,b)然后将*.c代码转换为共享对象(.so)。Cython的所有示例都说明了如何将这个.so导入python 但是,我对从C代码中读取这个共享对象感兴趣。当我编写一个示例C代码来读取.so时,它抛出一个错误,指出.pyx中实际存在的方法在.so对象中不存在 我想知道 a) 是否可以从其他语言(如C)读取Cython的共享对象 b) 而且,如果上面的语句是真的,那么我必须在代码中

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

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

我想知道 a) 是否可以从其他语言(如C)读取Cython的共享对象 b) 而且,如果上面的语句是真的,那么我必须在代码中做些什么更改才能从C中读取共享对象

谢谢

Python代码(另存为square_number.pyx)

Cython对应的setup.py文件

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

setup(
    ext_modules=cythonize("square_number.pyx"),
     )
用于将上述.pyx转换为.So的命令行语句(通过cython)

这将在同一个文件夹中创建一个方形编号.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;
 }
错误

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

我不记得这方面的细节,等我有了答案后,我可能会给出更详细的答案。然而,最基本的是Cython在导出与C兼容的SOs之前,先将python函数通过名称修改函数。然后,Python在导入Cython模块时会理解这个相同的名称,以便能够调用正确的函数

您需要做的是在cython模块上使用一个SO扫描库来计算实际调用的函数。要一次性完成此操作,请尝试运行:

readelf my\u cython\u so.so


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

将square\u number.pyx更改为:

cdef public int square_me(int x):
    return x * x
运行“setup.py”后,它将生成头文件“square_number.h”。 将其包含在主应用程序中。见下文:

将“main”函数更改为如下内容:

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

int main()
{
    Py_Initialize();
    initsquare_number();
    printf("%d",square_me( 4 ) );
    Py_Finalize();
    return 0;
}
#包括
#包括“方号h”
int main()
{
Py_初始化();
initsquare_数();
printf(“%d”,正方形(4));
Py_Finalize();
返回0;
}
编译此文件时,请确保链接到libpython.so和libsquare_number.so 您还需要通过向gcc提供-I标志来处理“Python.h”的include目录搜索路径


有关更多信息,请参见:

将字节码转换为汇编不涉及C。它可能涉及由C调用的类,或者以类似C的方式调用其他C类。但它仍然分别是字节码或程序集。你无法逆转从未发生过的事情。使用
objectdump-d-M
。要概述这些类,如果您仍然需要,请手动将这些类转换为C,然后感谢我们有python为我们这样做。

“我遇到了一个错误”什么错误?您也可以尝试Nuitka。但是,如果你不阅读错误消息,它将不会有帮助-没有什么会。告诉我们错误消息是什么-错误消息是您的朋友。抱歉,忘记添加错误。用错误更新了问题。当我编译C代码时,它无法在“square_number.pyx”@cdarke中找到函数“square_me”,谢谢你指向Nuitka。即使在纽特卡,它也抛出了同样的错误。我在纽特卡做了以下工作。a) 首先,我在python中创建了一个简单的“square_of_a_number”函数,b)在安装Nuitka之后,我通过命令(Nuitka--module python_module.py)创建了一个。尽管上面的语句创建了PYTHON_MODULE.so,但我无法从C中读取.so。我仍然得到了相同的错误(这是对a_编号的
平方的未定义引用)。我能够从您提供的C代码中读取共享对象。我有几个问题。从Cython准备好共享对象之后,为什么我们必须使用“Py_Initialize()”函数。共享对象不应该独立于python语言吗。另一个问题是,由于我们必须链接libpython.so和libsquare_number.so,我假设我们需要在编译c代码的机器上安装python和python模块,这是一个“python模块”。它应该由python解释器使用。类似于“输入平方数”。如果没有python解释器,这些共享对象将无法工作。关于Py_Initialize(),它初始化解释器并设置main、sys、sys.path等模块。假设您的pyx文件使用“import sys”,cython依赖解释器来处理这些导入。关于,libpython.so。是的,目标系统必须安装python。或者另一种方法是链接到静态python库(libpython.a)。但这会增加可执行文件的大小。所以这是一种交易-off@Icarus3如果我想在一台没有安装python的机器上测试这个程序,我会怎么做?如何模拟未安装python?后续问题:
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
cdef public int square_me(int x):
    return x * x
#include <Python.h>
#include "square_number.h"

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