c - 为 Python 扩展编译 C 文件时 Exec 格式错误

标签 c python-2.7 gcc archlinux-arm

我正在尝试使用一个简单的 C 文件来扩展 python。我成功创建了自己的 python 模块,但我还需要 C 文件本身作为独立的可执行文件进行编译和运行。我可以成功编译它,但是当我尝试运行它时,出现错误“无法执行二进制文件:Exec 格式错误”。

这是我的 C 源文件 (hellomodule.c):

#include <Python.h>

void print_hello(const char* name){
    printf("Hello %s!\n", name);
}

//Only used by Python
static PyObject*
say_hello(PyObject* self, PyObject* args)
{
    const char* name;

    if (!PyArg_ParseTuple(args, "s", &name))
        return NULL;

    //printf("Hello %s!\n", name);
    print_hello("World");

    Py_RETURN_NONE;
}

//Only used by Python
static PyMethodDef HelloMethods[] =
{
    {"say_hello", say_hello, METH_VARARGS, "Greet somebody."},
    {NULL, NULL, 0, NULL}
};

//Only used by Python
PyMODINIT_FUNC
inithello(void)
{
    (void) Py_InitModule("hello", HelloMethods);
}

int main(){
    print_hello("World");
}

我可以“成功”编译它,没有任何错误或警告,如下所示:

gcc -I /usr/include/python2.7 -c hellomodule.c -o hellomodule

使“hellomodule”文件可执行后,我运行它并收到错误:

-bash: ./hellomodule: cannot execute binary file: Exec format error

为什么会导致这样的错误?

最佳答案

您正在尝试执行一个目标文件,该文件不是可执行文件。要将代码编译为模块,您需要类似的东西

gcc -Wall -Werror -Wextra -O2 -I/usr/include/python2.7 \
    -shared hellomodule.c -o hellomodule.so -lpython2.7

但是要正确链接到所有内容并添加所有可能的包含目录,有一个名为 python-config 的脚本,您只需像这样调用它

gcc -Wall -Werror -Wextra -O2 `python-config --includes` \
    -shared hellomodule.c -o hellomodule.so `python-config --libs`

更好的是,该脚本还提供了CFLAGSLDFLAGS,所以最后

gcc -Wall -Werror -Wextra -O2 `python-config --cflags` \
    -shared hellomodule.c -o hellomodule.so `python-config --ldflags`

然后,将生成的文件复制到 /usr/lib/python2.7/site-packages

之后,您可以像这样在 python 脚本中加载模块

import hellomodule

目标文件是链接器最终使用的中间二进制文件(ld 可能)来生成最终的二进制文件。 Python 模块没有 main() 函数,它必须是一个运行时可加载共享对象,它导出一些预定义符号,Python 解释器将使用这些符号将模块加载到 Python 脚本/程序中。

注意:要正确执行此操作,而不是尝试创建 Makefile,如下所示

CFLAGS = `python-config --cflags` -Wall -Werror # add more if needed
LDFLAGS = `python-config --ldflags` # add more if needed
OBJS = hellomodule.o # add more if needed

all: $(OBJS)
    $(CC) $(CFLAGS) $(LDFLAGS) -shared -o modulename.so $(OBJS)

%.o: %.c
    $(CC) -c $(CFLAGS) $<

确保使用制表符而不是空格进行缩进,然后在 Makefile 和源文件所在的同一目录中运行 make是。

关于c - 为 Python 扩展编译 C 文件时 Exec 格式错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34666606/

相关文章:

c++ - 最佳实践 : Should I create a typedef for byte in C or C++?

python - 如何为特定版本的 Python 创建虚拟环境?

c++ - 默认模板类参数混淆了 g++?

c++ - Solaris 下 Sun Studio 10 中的链接错误

ios - 使用 iOS 7 在越狱的 iOS 设备上在/var/mobile/Library/APP NAME 中创建文件夹

python - 为测试类中的所有测试处理相同的 Python 异常

python - 在python2.7.5上安装pip及旧版本问题

c++ - 从 C++ 代码中剥离注释,同时保留行号

c++ - GCC 编译器标志 "-DEVAL"

c - 插入和弹出功能