C动态加载文件太短了?

时间:2016-11-22 02:12:15

标签: c dlopen

我尝试使用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示例。这是否意味着文件需要具有一定的大小才能动态加载,或者这些文件的编译方式是否有问题?

我觉得我错过了一些简单的事情。

如何让程序按预期执行?

2 个答案:

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