2016-11-22 65 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);