Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

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

27 views
Skip to first unread message

luser- -droog

unread,
Jul 31, 2013, 5:21:24 PM7/31/13
to
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

Eric Sosman

unread,
Jul 31, 2013, 5:28:47 PM7/31/13
to
On 7/31/2013 5:21 PM, luser- -droog wrote:
>[...]
This is not a Standard C header, so (in principle) we have
no idea what it does or what effect it has on the rest of your
code. The nice folks at comp.unix.programmer, however, are
fully cognizant of dynamic libraries and are in a better position
to offer useful advice.

--
Eric Sosman
eso...@comcast-dot-net.invalid

James Kuyper

unread,
Jul 31, 2013, 5:32:20 PM7/31/13
to
On 07/31/2013 05:21 PM, luser- -droog wrote:
> 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!

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.

luser- -droog

unread,
Jul 31, 2013, 5:53:04 PM7/31/13
to
Ooops. Thanks fellas.

--
sorry for the mess.
0 new messages