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