python - gcc 链接器的问题 - 为 python 编译 c 函数

标签 python c gcc linker

我正在尝试编译我在 github 上找到的一些基于 c 的视频解码器函数,以便在 python 中将它们作为函数运行。不幸的是,我遇到了 gcc 链接器问题。我对从命令行编译 c 感到非常沮丧(我曾经在 eclipse 中做过一次)。

这是我从命令行运行的

gcc -dynamiclib -I/usr/include/python2.7/ -lpython2.7 -o _decoder.dylib _decoder.c

我还尝试添加这些选项来帮助链接器找到定义“缺失”函数的 .c 和 .h 文件的链接(它们都在同一目录中,我将其路径缩写为 $ PATHTOCFILESDIR)

-I/$PATHTOCFILESDIR/uvlc-decoder.c
-I/$PATHTOCFILESDIR/uvlc-decoder.h

这里是错误:

Undefined symbols for architecture x86_64: 
  "_Video_uvlc_decode_frame", referenced from:
    ___decode_uvlc_frame in _decoder-db7728.o 
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1

在用谷歌查看后,我查看了所有其他 c 和 h 文件,试图找到 gcc 找不到 Video_uvlc_decode_frame 函数的原因,但它对我来说并不是立即透明的。我唯一的猜测是(如下所示)我注意到整个文件中有几行,例如“FE_INTERNAL”,这是我在我对 C 的知识之外发现的。我相信这是针对 Sphinx 的,它没有安装在我的构建中。这会导致这些链接器问题吗?

这里是相关代码的缩减:

链接器指向错误的文件顶部:

_decoder.c

#include <string.h>
#include "idct8.h"
#include "uvlc-decoder.h"
#include "_decoder.h"


static PyObject *
__decode_uvlc_frame (
    PyObject *self,
    PyObject *args
)
{
    PyObject *input_buffer;

    if (!PyArg_ParseTuple(args, "S:decode_h263_uvlc", &input_buffer))
         return NULL;

    return Video_uvlc_decode_frame(input_buffer);
}

(我认为)应该指向“缺失”函数的包含文件的声明:

uvlc-decoder.h

#ifndef __VIDEO_UVLC_DECODER_H__
#define __VIDEO_UVLC_DECODER_H__

#include <stdint.h>
#include <stdbool.h>

#include <Python.h>

#include "utils.h"


FE_INTERNAL
PyObject *
Video_uvlc_decode_frame (
    PyObject *input_buffer
);


#endif

编辑:我在目录的另一个文件中找到了 FE_INTERNAL 的定义:

utils.h

#ifdef __GNUC__
#   define FE_LIKELY(x)    __builtin_expect((x), 1)
#   define FE_UNLIKELY(x)  __builtin_expect((x), 0)
#   define FE_INTERNAL     __attribute__((visibility("hidden")))
#else
#   define FE_LIKELY(x)    (x)
#   define FE_UNLIKELY(x)  (x)
#   define FE_INTERNAL
#endif

EDIT2:这最初不是透明的,但我相信还有一个文件改变了答案。以下是相关信息:

uvlc-decoder.c

#include <stdlib.h>
#include <string.h>

#include "idct8.h"
#include "uvlc-decoder.h"
#include "uvlc-decoder-priv.h"

/*
number of other functions defined here that have been removed for brevity
*/

PyObject *
Video_uvlc_decode_frame (
    PyObject *input_buffer
)
{
    __DecoderState  dec_state;
    PyObject       *picture_desc = NULL;

    dec_state.out_picture_buf = NULL;
    dec_state.bitstream = FeDrone_BitStreamReader_new(input_buffer);

    if (FE_LIKELY(__decoder_read_frame(&dec_state))) {
        picture_desc = Py_BuildValue("(IIIs#)",
                                     dec_state.pic_header.width,
                                     dec_state.pic_header.height,
                                     dec_state.pic_header.frame_nr,
                                     (char *)dec_state.out_picture_buf,
                                     (int)dec_state.out_picture_len);
    }

    PyMem_FREE(dec_state.out_picture_buf);
    dec_state.out_picture_buf = NULL;

    Video_BitStreamReader_free(dec_state.bitstream);
    dec_state.bitstream = NULL;

    return picture_desc;
}

编辑3:

我使用的最终 gcc 命令:

gcc -dynamiclib `python-config --cflags` `python-config --ldflags` -o _decoder.so *.c

此命令将使用我正在开发的 python 框架的本地构建(macports 构建)。 *.c 基本上告诉 gcc 在链接时使用当前文件夹中的所有 .c 文件。

最佳答案

你需要一个 body

FE_INTERNAL
PyObject *
Video_uvlc_decode_frame (
    PyObject *input_buffer
);

喜欢

 PyObject *
    Video_uvlc_decode_frame (
        PyObject *input_buffer
    )
{
 return input_buffer;
}

关于python - gcc 链接器的问题 - 为 python 编译 c 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24687397/

相关文章:

objective-c - 关于 Cocoa C 风格函数的一些愚蠢问题

c - 如何在 gcc asm 中添加一个计数器?

c++ - 什么会导致 HP-UX 和 LINUX for C++ 应用程序的返回值不同?

c - Clang 中的模拟 GCC '-ffshort-double'

python - 用Python重写的C CRC计算方法好像不对

python - Seaborn X 轴分类数据

python - 在 numpy 数组的末尾追加数组的 n 个副本

python - 使用 for 循环迭代文本文件中的各个单词

控制可能到达非空函数 C 的结尾

c - x264编码帧率限制