0

我目前正处于我的计算机工程高级项目的最终开发和测试阶段。在使用库(Libjpeg、Libbmp、PocketSphinx、Libavcodec、Libavformat、Libavutil)并使用 netbeans 作为 IDE 进行代码(C、Bash)的设计和开发之后。我遇到的问题是,在 Netbeans 中,代码可以完美地编译和链接,并且软件的执行也很好。但是,当我使用 MakeFile 从外部编译和链接代码时,诸如:fopenfreadfwritefgetsfscanf等的函数停止工作......

GCC标志:

-m32 -O3 -W -Wall -std=gnu99 -pedantic -Wbad-function-cast -Wcast-align -Wcast-qual \
-Wchar-subscripts -Winline -Wmissing-prototypes -Wnested-externs -Wpointer-arith \
-Wredundant-decls -Wshadow -Wstrict-prototypes -Wwrite-strings -Wformat-nonliteral \
-Wformat-security -ftrapv -lrt -Wno-unused \
-DMODELDIR=\"`pkg-config --variable=modeldir pocketsphinx`\" \
`pkg-config --cflags --libs pocketsphinx sphinxbase` \
`pkg-config --cflags --libs sndfile`

LD标志:

-I/usr/local/lib -I/usr/local/include -I/usr/local/lib/pkgconfig -lpthread \
-lpocketsphinx -lsndfile -ljpeg -lavformat -lavcodec -ldl -lasound -lz -lswscale \
-lavutil -lm

同样的未知行为也影响了现在无法打开 HMM 的 PocketSphinx 的性能。

任何启发都非常感谢,因为我的最后一次演讲是下周。

- - - - - 更新 - - - - -

这是我实际的 MakeFile

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

# Compiler and Flags 
CC = gcc
CFLAGS = -m32 -O3 -W -Wall -std=gnu99 -pedantic -Wbad-function-cast -Wcast-align -Wcast-qual -Wchar-subscripts -Winline -Wmissing-prototypes -Wnested-externs -Wpointer-arith -Wredundant-decls -Wshadow -Wstrict-prototypes -Wwrite-strings -Wformat-nonliteral -Wformat-security -ftrapv -Wno-unused -DMODELDIR=\"`pkg-config --variable=modeldir pocketsphinx`\"`pkg-config --cflags --libs pocketsphinx sphinxbase` `pkg-config --cflags --libs sndfile`

# Libraries
LIBS = -I/usr/local/lib -I/usr/local/include -I/usr/local/lib/pkgconfig -lpocketsphinx -lsndfile -ljpeg -lavformat -lavcodec -ldl -lasound -lz -lswscale -lavutil -lm

# Source files
SRC= libbmp.c state.c secure.c audio.c config.c engine.c helpers.c macmp2.c queue.c image.c video.c

# Object Files
OBJ= libbmp.o state.o secure.o audio.o config.o engine.o helpers.o macmp2.o queue.o image.o video.o

# Executable file
EXECUTABLE = macmp2

# Explicit rule
hist: $(OBJ)
    $(CC) $(CFLAGS) -o $(EXECUTABLE) $(OBJ) $(LIBS)

clean:
    rm -f *.o
    rm -f $(EXECUTABLE)

# Implicit rules
audio.o: macmp2.h libbmp.h audio.c
config.o: macmp2.h libbmp.h config.c
engine.o: macmp2.h libbmp.h engine.c
helpers.o: macmp2.h libbmp.h helpers.c
image.o: macmp2.h libbmp.h image.c
libbmp.o: libbmp.h libbmp.c
macmp2.o: macmp2.h libbmp.h macmp2.c
queue.o: macmp2.h libbmp.h queue.c
secure.o: macmp2.h libbmp.h secure.c
state.o: macmp2.h libbmp.h state.c
video.o: macmp2.h libbmp.h video.c

编译时错误:无运行时错误:无

我首先注意到这部分代码中的问题。

void load_configuration (macmp2_state * s)
{
    register uint32_t it = 0x0;                     /* Iterator */
    register uint32_t size = get_file_size (s);     /* Configuration File Size */
    char * new_entry = (char *) malloc_safe (sizeof (char) * LINE_LENGTH * 5, s);
    char * error_msg = (char *) malloc_safe (sizeof (char) * LINE_LENGTH * 5, s);
    char * filename = NULL;                         /* Filename Token */
    char * pmode = NULL;                            /* Processing Mode Token */
    char * token = NULL;                            /* String Token */
    FILE * fp = NULL;                               /* File Pointer */

    /* Temporary Variables */
    video_file * v = (video_file *) malloc_safe (sizeof(*v), s);
    image_file * i = (image_file *) malloc_safe (sizeof(*i), s);
    audio_file * a = (audio_file *) malloc_safe (sizeof(*a), s);

#ifdef DEBUG
    fprintf (stderr, "Reading configuration file.\n");
#endif

    fp = fopen_safe (s->config_file, "r", s);

    for (it = size; it > 0x0; it--)
    {
        /* Initializing Variables */
        memset (new_entry, '\0', LINE_LENGTH * 5);
        init_video_file (v);
        init_image_file (i);
        init_audio_file (a);

        /* Extracting entry from configuration file */        
        if (fgets (new_entry, (LINE_LENGTH * 5 * sizeof(char)), fp) == NULL)
        {
            fatal_error (s, "Error reading configuration file.");
        }

使用 MakeFile 编译时,我总是收到“读取配置文件时出错”,但是我在 Netbeans 上没有。

程序输入:./macmp2 -c configuration.txt 输出:读取配置文件。

[*] 致命错误:读取配置文件时出错。

正如我所说,代码是我的高级项目,我不能在这里发布。我很确定这个问题与链接器标志有关。程序在第一次迭代时停止。正如我之前所说,代码在使用 Netbeans 编译时有效,但在使用发布的 MakeFile 编译时停止工作。

- - - - - 更新 - - - - -

根据 Jonathan Leffler 的要求,这里是 fopen_safe 和 malloc_safe 的包装器。

fopen_safe 和 malloc_safe 的代码都是由我实现的。

void * malloc_safe (size_t size, macmp2_state * s)
{
    void * ptr = malloc (size);

    if (ptr == NULL)
    {
        fatal_error (s, "Memory could not be allocated.");
    }
    return ptr;
}

FILE * fopen_safe (const char * filename, const char * mode, macmp2_state * s)
{
    FILE * stream = fopen (filename, mode);

    if (stream == NULL)
    {
        fatal_error (s, "Stream could not be open.");
    }
    return stream;
}
4

2 回答 2

2

您的链接标志(您的问题中的“ld-flags”)顺序错误。

链接器的程序参数顺序(ld经常通过 thru 调用gcc)很重要。您应该首先放置源文件(for gcc),然后是目标文件(按依赖顺序),然​​后是库(从高级系统库到低级系统库)。例如,你-lpthread应该定位在-lavformat

但是你真的应该学会写Makefile-s。不知道你有没有时间。好的做法是Makefile在项目开始时开始并改进它(随着您改进代码)。

于 2012-02-14T17:16:55.360 回答
0

Your code compiles just fine in both situations (including the linker being satisfied).

Then you run it in both situations and in the latter, when having built it using make, you get an unexpected result.

To me, this looks more like you not checking the environment where you run your application. The documentation for fgets clearly states that NULL is returned not only on error but also if no bytes have been read when EOF is encountered.

If you really want to know which file is opened, use strace, and make sure that you run the application in the expected environment with the proper configuration file in its proper place. I'm sure this will let you find the problem.

于 2012-02-21T16:53:17.007 回答