Search code examples
cdlopen

C Dynamic loading file too short?


I'm trying out dynamic loading with C and I've run into a problem at the very set out. I have a small program that loads an object at run time. The object contains a single function that writes some messages to stdin. This has been compiled on OS X 10.10 with clang. Here is the code:

/* 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;

}

Here is module.h:

/* module.h */

int
function();

Here is 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;
}

Here is the Makefile:

loader : loader.c module.o
    cc  -Wall loader.c -ldl -o loader

module.o : module.c
    cc -Wall -fpic -c module.c

This compiles without warnings, but it does not execute the way I expect. The program returns the following error:

Error: dlopen(/users/user/dev/module.o, 2): no suitable image found. Did find: /users/user/dev/module.o: file too short.

I've had a look and there is not very much out there on this error message. This program was based on the dlopen example from TLDP. Does this mean that the files need to be of a certain size in order to be dynamically loaded, or is there something wrong with the way these files have been compiled?

I feel like I'm missing something simple.

How do I get this program to execute as expected?


Solution

  • dlopen loads shared libraries (*.so), not normal object files (*.o). They are incompatible formats.

    For gcc, you should be outputting to libmodule.so and using the -shared flag to create a shared library (I'm not sure if cc uses the same flags).