【问题标题】:Trouble with gcc linker - compiling c functions for pythongcc 链接器的问题 - 为 python 编译 c 函数
【发布时间】:2014-07-10 22:33:04
【问题描述】:

我正在尝试编译一些我在 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

在与 google 一起查看后,我查看了所有其他 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;
}

EDIT3:

我使用的最终 gcc 命令:

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

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

【问题讨论】:

    标签: python c gcc linker


    【解决方案1】:

    你需要一个身体

    FE_INTERNAL
    PyObject *
    Video_uvlc_decode_frame (
        PyObject *input_buffer
    );
    

    喜欢

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

    【讨论】:

    • 产生警告:./uvlc-decoder.h:17:1: 警告:控制到达非空函数的结尾 [-Wreturn-type] }
    • PyObject * Video_uvlc_decode_frame (PyObject *input_buffer) { return input_buffer; }
    • 太棒了。谢谢。都在工作。您介意解释一下为什么需要这样做吗?
    • 您收到的消息实际上来自链接器,而不是来自编译器。在读取所有输入文件并完成所有符号解析后,链接编辑器将在内部符号表中搜索任何未绑定到符号定义的符号引用。这些符号引用称为未定义符号。未定义的符号会根据符号的类型以及生成的输出文件的类型影响链接编辑过程。
    • 这意味着您没有编写函数,或者您没有创建变量,或者您没有链接到包含缺少的函数或变量的库或目标代码。这意味着链接器已经查看了您告诉它的所有编译代码,但仍然找不到它要查找的内容。
    猜你喜欢
    • 2012-01-16
    • 1970-01-01
    • 2021-09-18
    • 1970-01-01
    • 1970-01-01
    • 2021-02-24
    • 2010-09-17
    • 2020-01-17
    • 2016-06-23
    相关资源
    最近更新 更多