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);