Simple dynamic loading example (review requested) -- Am I missing something?

Discussion in 'C Programming' started by luser- -droog, Jul 31, 2013.

  1. I've avoided learning about dynamic loading for a long time, but
    found that I need to learn to do it for things like multiple output
    devices and running the whole program as a library call instead of
    standalone. (This is all in the context of my Postscript Interpreter,
    code.google.com/p/xpost)

    So I read http://en.wikipedia.org/wiki/Dynamic_loading
    and followed a link to a Linux page, and whipped up this little
    example/test. And it works!

    But it can't be that easy, right? I've got to be missing something.

    Please comment on the following code. (Ignore for the moment
    the lack of error handling in the stack implementation; I'm mostly
    interested in the interfacing.)

    test.c:

    /*
    Dynamic Loading test
    ref.
    http://en.wikipedia.org/wiki/Dynamic_loading
    http://linux4u.jinr.ru/usoft/WWW/www_debian.org/Documentation/elf/node7.html
    */
    #include <dlfcn.h>
    #include <stdio.h>
    #include <stdlib.h>

    #include "stack.h"

    void fatal(char *msg) {
    fprintf(stderr, "Fatal Error: %s\n", msg);
    exit(EXIT_FAILURE);
    }

    struct Stack_interface *si;

    void loadplugins (void) {
    void *stack_library = dlopen("stack.so", RTLD_LAZY);
    if (stack_library == NULL) fatal("unable to load stack");
    si = dlsym(stack_library, "interface");
    if (si == NULL) fatal("unable to load stack interface");
    }


    int main() {
    loadplugins();
    void *stack;
    char *a = "A";
    char *b = "B";
    void *c;

    stack = si->stack_init();
    stack = si->push(stack, a);
    stack = si->push(stack, b);
    stack = si->pop(stack, &c);
    printf("%s\n", (char *)c);
    stack = si->pop(stack, &c);
    printf("%s\n", (char *)c);
    return 0;
    }



    stack.h:


    struct Stack_interface {
    void *(*stack_init) (void);
    void *(*push) (void *stack, void *item);
    void *(*pop) (void *stack, void **item);
    };



    stack.c:


    #include <stdlib.h>
    #include <string.h>

    #include "stack.h"
    /*
    struct Stack_interface {
    void *(*stack_init) (void);
    void *(*push) (void *stack, void *item);
    void *(*pop) (void *stack, void **item);
    };
    */

    void *stack_init (void);
    void *push(void *stack, void *item);
    void *pop(void *stack, void **item);

    struct Stack_interface interface = {
    stack_init,
    push,
    pop
    };

    typedef struct stack {
    void *item;
    struct stack *next;
    } Stack;

    void *stack_init (void) {
    Stack *s;
    s = malloc(sizeof*s);
    if (s) {
    s->item = NULL;
    s->next = NULL;
    }
    return s;
    }

    void *push (void *stack, void *item) {
    Stack *s = stack;
    Stack *n = stack_init();
    n->item = item;
    n->next = s;
    return n;
    }

    void *pop (void *stack, void **item) {
    Stack *s = stack;
    Stack *n = s->next;
    *item = s->item;
    free(s);
    return n;
    }


    makefile:

    CC=gcc
    LDFLAGS=
    #LDFLAGS=-rdynamic #Cygwin doesn't need
    SHLDFLAGS=

    all: test

    stack.o: stack.c
    $(CC) -c -fPIC $<

    stack.so: stack.o
    $(CC) $(SHLDFLAGS) -shared -o $@ $^

    test: test.o stack.so
    $(CC) $(LDFLAGS) -o $@ test.o -ldl

    clean:
    $(RM) stack.o stack.so test.o test.exe
     
    luser- -droog, Jul 31, 2013
    #1
    1. Advertisements

  2. luser- -droog

    Eric Sosman Guest

    Eric Sosman, Jul 31, 2013
    #2
    1. Advertisements

  3. luser- -droog

    James Kuyper Guest

    Dynamic loading is OS-specific. To get the best answers to questions
    about such things, you should post them to a forum specific to the
    relevant OS; in this case, one such forum would be comp.unix.programmer.
     
    James Kuyper, Jul 31, 2013
    #3
  4. Ooops. Thanks fellas.
     
    luser- -droog, Jul 31, 2013
    #4
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.