我尝试使用C进行动态加载,并且我已经在出现问题时遇到了问题。我有一个小程序在运行时加载一个对象。该对象包含一个将一些消息写入stdin的函数。这已经在OS X 10.10上用clang编译。这是代码:
/* loader.c */
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
#include "module.h"
int main(int argc, char **argv) {
char file[] = "/users/user/dev/module.o";
void *handle;
int (*function)();
handle = dlopen(file, RTLD_NOW);
if (!handle) {
printf("Cannot load program. Error: %s\n", dlerror());
return 1;
}
program = dlsym(handle, "function");
printf("Program loaded");
function();
printf("Exiting");
return 0;
}
这是module.h:
/* module.h */
int
function();
这是module.c:
/* module.c */
#include <stdio.h>
#include <unistd.h>
int function() {
printf("Hello from module");
sleep(1);
printf("Hello from module again");
return 0;
}
这是Makefile:
loader : loader.c module.o
cc -Wall loader.c -ldl -o loader
module.o : module.c
cc -Wall -fpic -c module.c
这会在没有警告的情况下编译,但它不会按照我的预期执行。该程序返回以下错误:
Error: dlopen(/users/user/dev/module.o, 2): no suitable image found. Did find: /users/user/dev/module.o: file too short
。
我看过这个错误消息并没有那么多。该程序基于TLDP的dlopen
示例。这是否意味着文件需要具有一定的大小才能动态加载,或者这些文件的编译方式是否有问题?
我觉得我错过了一些简单的事情。
如何让程序按预期执行?
答案 0 :(得分:3)
mt19937ar_no_main.c
加载共享库(dlopen
),而不是普通的目标文件(*.so
)。它们是不兼容的格式。
对于gcc,您应该输出到*.o
并使用libmodule.so
标志来创建共享库(我不确定-shared
是否使用相同的标志)。
答案 1 :(得分:0)
函数dlopen()
加载由以null结尾的字符串文件名命名的动态库文件,并为动态库返回不透明的“句柄”。动态库的扩展名是.so。
在您的程序中,您只需将模块构建到一个对象中,该对象是一个.so文件。如果要使用dlopen()
,则必须将程序构建到动态库中。
以下是您的示例:
module.so : module.c
cc -Wall -shared -fpic -c module.c
然后您可以在程序中加载.so文件:
dlopen("SO_PATH/module.so", RTLD_NOW);