Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I load my own library dynamically, and invoke a method in it?

I'd like to write some C code (okay if it only works on Linux) to dynamically load a new shared library, and then invoke a method from it (to be determined at runtime). It seems this is already possible because java can load native libraries dynamically, and then invoke methods from them.

For example, I'd like to do something like:

int main() {
    libinfo_t * lib_details = load_shared_library("libfoo.so");
    run_method(lib_details, "bar", 7);
}

This would invoke the method 'bar' with argument 7 (bar is a method compiled into libfoo.so).

Use case details:

I'd like to compile a binary that loads all the shared libraries in a directory, and runs some method from each, in the memory context of the original program. I'd like to be able to quickly enable or disable a shared library by adding/removing it from a directory.

Proof of concept:

It seems this should be possible, based on the way java manages to link with jni code dynamically. You can use System.load(), and load the library of your choice. Coupled with compiling from memory, it seems it would allow you to run an arbitrary function from an arbitrary library. http://www.java2s.com/Code/Java/JDK-6/CompilingfromMemory.htm

Things I've tried:

  1. I've looked at the manpage for 'uselib', which seems useful, but I'm not sure what to do with the library once I've loaded it.

  2. A bit of googling returned http://dyncall.org/, but this isn't exactly what I need -- this project still requires a function pointer to make the function call.

I'd be grateful for any pointer on where to look next, even without a concrete answer. Thanks!

like image 497
jstrom Avatar asked Feb 19 '13 03:02

jstrom


1 Answers

Linux has a very complete API for this. It's the dlopen(3) API.

First, you call dlopen with a filename to get a shared library handle:

void* lib = dlopen("./lib.so");

Than, to get a function pointer for a function in this library:

int (*func)() = dlsym(lib, "thing");

Use this pointer as you please.

Finally, when you're done:

dlclose(lib)

Note: Remember to do error checking!

like image 143
Linuxios Avatar answered Nov 03 '22 01:11

Linuxios