对于作为原型的函数,dlopen未能定义未定义的符号

时间:2014-11-11 14:33:38

标签: c shared-libraries dlopen undefined-symbol

我正在用C11在Linux(64位)上编写一个共享库。

我创建了3个C和H文件。

dll.c

#include "dllman.h"

void start(){
    pipeListeningThreadFunc( NULL );
}

dllman.h

#include <stdio.h>

void* pipeListeningThreadFunc( void* args );

dllman.c

#include "dllman.h"

void* pipeListeningThreadFunc( void* args ){
    printf("Blah");
    return NULL;
}

编译代码如下

gcc -std=gnu11 -c -Wall -Werror -fpic -lpthread dll.c
gcc -std=gnu11 -shared -fpic -o dll.so dll.o

到目前为止,一切都还可以。 dll.so文件已创建。但是,当我使用dlopen函数加载带有as:

的库时

test.d

...
void* lh = dlopen("./dll.so", RTLD_NOW | RTLD_GLOBAL);
...

dlerror给了我: dlopen错误:./ dll.so:未定义的符号:pipeListeningThreadFunc

我不明白这有什么问题。

为了能够理解这个问题,我将函数pipeListeningThreadFunc的实现移到了dllman.h,并以相同的方式编译。这一次一切正常。

将函数定义为原型有什么问题?为什么在头文件中将其定义为原型并在C文件中实现时,无法找到该函数?

1 个答案:

答案 0 :(得分:2)

我认为你应该执行以下命令:

gcc -std=gnu11 -c -Wall -Werror -fpic -lpthread dll.c
gcc -std=gnu11 -c -Wall -Werror -fpic -lpthread dllman.c
gcc -std=gnu11 -shared -fpic -o dll.so dll.o dllman.o

您的命令缺失dllman.c

Linux允许构建缺少某些符号的库(在您的情况下,dll.so不包含pipeListeningThreadFunc函数)。但是,加载库时,必须在任何位置找到pipeListeningThreadFunc - 无论是在此库还是其他库中。由于此功能不存在,dlopen失败。