Question

I'm writing a program in C which allows users to implement custom "functions" to be run by an interpreter of sorts. I also want to allow users to write these custom functions in plain C, and then be loaded in dynamically. In order to do this, I created two structs, one for interpreted functions, and one for native ones.

Here's a simplified example:

struct func_lang {
    bool is_native;
    char* identifier;
    // various other properties
}

typedef void (*func_native_ptr)(int);
struct func_native {
    bool is_native;
    char* identifier;
    func_native_ptr func_ptr;
}

I then use the identifier property of each struct to put them in a hashtable, which I can then use to execute them at runtime.

My problem is actually from the other end, the loaded libraries. I'd like to be able to allow the loaded libraries to "publish" which functions they want inserted into the list. For example, maybe with a function like this:

void register_func_native(char* identifer, func_native_ptr func_ptr);

Then, when I would call an init function from the library, they could call this function to insert the functions into the hashtable.

Will this work? I'm a little confused about how the register_func_native function would be linked, since it's needed by the loaded library, but would have to be defined by the loader itself. Does my loader function need to be implemented in another shared library, which could then be linked at runtime?

Was it helpful?

Solution

This will depend on the platform, but on Linux and all the Unixes I've seen, this will work. Example:

$ cat dll.c
void print(char const *);

void foo()
{
    print("Hello!");
}
$ gcc -Wall -shared -fPIC -o dll.so dll.c
$ cat main.c
#include <dlfcn.h>
#include <stdio.h>

void print(char const *msg)
{
    puts(msg);
}

int main()
{
    void *lib = dlopen("./dll.so", RTLD_NOW);
    void (*foo)() = (void (*)())dlsym(lib, "foo");
    foo();
    return 0;
}
$ cc -fPIC -rdynamic main.c -ldl
$ ./a.out 
Hello!

OTHER TIPS

It will work. The shared library sees all the global symbols you have in your main program.

In the main program you'll need dlopen() and dlsym() to call the initialization function.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top