我正在尝试编译我在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);
}
包含文件的声明(我认为)应该指向&#34;缺少&#34;功能:
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 build)。 * .c基本上告诉gcc在链接时使用当前文件夹中的所有.c文件。
答案 0 :(得分:1)
你需要一个身体
FE_INTERNAL
PyObject *
Video_uvlc_decode_frame (
PyObject *input_buffer
);
喜欢
PyObject *
Video_uvlc_decode_frame (
PyObject *input_buffer
)
{
return input_buffer;
}