2016-11-22 68 views
3

我试着动态加载与C和我已经遇到了问题,在非常设置。我有一个运行时加载对象的小程序。该对象包含一个将某些消息写入stdin的函数。这是在OS X 10.10上使用clang编译的。下面是代码:C动态加载文件太短?

/* loader.c */ 

#include <stdlib.h> 
#include <stdio.h> 
#include <dlfcn.h> 
#include "module.h" 

int main(int argc, char **argv) { 

    char file[] = "https://stackoverflow.com/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

dlopen负载共享库(*.so),不正常的对象文件(*.o)。它们是不兼容的格式。

对于gcc,您应该输出到libmodule.so并使用-shared标志来创建共享库(我不确定cc是否使用相同的标志)。

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