C动态加载文件太短?
C Dynamic loading file too short?
我正在尝试使用 C 进行动态加载,但我 运行 一开始就遇到了问题。我有一个在 运行 时间加载对象的小程序。该对象包含一个将一些消息写入标准输入的函数。这是在 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;
}
这是生成文件:
loader : loader.c module.o
cc -Wall loader.c -ldl -o loader
module.o : module.c
cc -Wall -fpic -c module.c
编译时没有警告,但没有按我预期的方式执行。程序returns出现如下错误:
Error: dlopen(/users/user/dev/module.o, 2): no suitable image found. Did find: /users/user/dev/module.o: file too short
.
我看过了,关于这个错误信息的内容并不多。该程序基于 TLDP 中的 dlopen
示例。这是否意味着文件需要一定大小才能动态加载,或者这些文件的编译方式有问题?
我觉得我缺少一些简单的东西。
如何让这个程序按预期执行?
dlopen
加载 shared 库 (*.so
),而不是普通目标文件 (*.o
)。它们是不兼容的格式。
对于 gcc,您应该输出到 libmodule.so
并使用 -shared
标志创建共享库(我不确定 cc
是否使用相同的标志)。
函数dlopen()
加载以空字符结尾的字符串文件名命名的动态库文件,returns为动态库加载一个不透明的"handle"。动态库的扩展名为.so。
在您的程序中,您只是将模块构建到一个对象中,该对象是一个 .so 文件。如果你想使用dlopen()
,你必须将你的程序构建成一个动态库。
下面是一个例子:
module.so : module.c
cc -Wall -shared -fpic -c module.c
然后你就可以在你的程序中加载.so文件了:
dlopen("SO_PATH/module.so", RTLD_NOW);
我正在尝试使用 C 进行动态加载,但我 运行 一开始就遇到了问题。我有一个在 运行 时间加载对象的小程序。该对象包含一个将一些消息写入标准输入的函数。这是在 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;
}
这是生成文件:
loader : loader.c module.o
cc -Wall loader.c -ldl -o loader
module.o : module.c
cc -Wall -fpic -c module.c
编译时没有警告,但没有按我预期的方式执行。程序returns出现如下错误:
Error: dlopen(/users/user/dev/module.o, 2): no suitable image found. Did find: /users/user/dev/module.o: file too short
.
我看过了,关于这个错误信息的内容并不多。该程序基于 TLDP 中的 dlopen
示例。这是否意味着文件需要一定大小才能动态加载,或者这些文件的编译方式有问题?
我觉得我缺少一些简单的东西。
如何让这个程序按预期执行?
dlopen
加载 shared 库 (*.so
),而不是普通目标文件 (*.o
)。它们是不兼容的格式。
对于 gcc,您应该输出到 libmodule.so
并使用 -shared
标志创建共享库(我不确定 cc
是否使用相同的标志)。
函数dlopen()
加载以空字符结尾的字符串文件名命名的动态库文件,returns为动态库加载一个不透明的"handle"。动态库的扩展名为.so。
在您的程序中,您只是将模块构建到一个对象中,该对象是一个 .so 文件。如果你想使用dlopen()
,你必须将你的程序构建成一个动态库。
下面是一个例子:
module.so : module.c
cc -Wall -shared -fpic -c module.c
然后你就可以在你的程序中加载.so文件了:
dlopen("SO_PATH/module.so", RTLD_NOW);