I have been reading the on-line book Basics of libuv and trying to rewrite them to work with both a static link and a dynamic link to the libuv library. I rewrote the watchers example (code below), but I had to "rename" the functions I retrieved from libuv.dylib to make it work, which means I had to write an entirely separate code path for the dynamic linking case. Can I somehow keep the same function names?
I want my code to look like this.
#include <stdio.h>
#include <uv.h>
#ifdef DYNAMIC
#include <dlfcn.h>
#endif
int64_t counter = 0;
void wait_for_a_while(uv_idle_t *handle, int status) {
counter++;
if (counter >= 10e6)
uv_idle_stop(handle); // This function pointer must be a global variable
}
int main(int argc, char **argv) {
uv_idle_t idler;
// Initialize code needed for dynamically-linked library
#ifdef DYNAMIC
void *lib_handle = dlopen("libuv.dylib", RTLD_LOCAL|RTLD_LAZY);
// Set up pointers to functions defined in libuv.dyld ...
#endif
uv_idle_init(uv_default_loop(), &idler);
uv_idle_start(&idler, wait_for_a_while);
printf("Idling...\n");
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
// Clean up dynamically linked code
#ifdef DYNAMIC
dlclose(lib_handle);
#endif
return 0;
}
Currently, it looks like this.
#include <stdio.h>
#include <uv.h>
#ifdef DYNAMIC
#include <dlfcn.h>
// Currently, I need to define function pointers with different names
// than the functions they call
uv_loop_t* (*uln)(void);
int (*ur)(uv_loop_t*, uv_run_mode);
uv_loop_t* (*udl)(void);
int (*uii)(uv_loop_t*, uv_idle_t*);
int (*uist)(uv_idle_t*, uv_idle_cb);
int (*uisp)(uv_idle_t*);
#endif
int64_t counter = 0;
void wait_for_a_while(uv_idle_t *handle, int status) {
counter++;
if (counter >= 10e6)
#ifdef DYNAMIC
uisp(handle);
#else
uv_idle_stop(handle); // This should be the only line remaining
#endif
}
int main(int argc, char **argv) {
uv_idle_t idler;
// Code path for dynamic linking case
#ifdef DYNAMIC
void *lib_handle = dlopen("libuv.dylib", RTLD_LOCAL|RTLD_LAZY);
// Retrieve symbol names from libuv.dylib
*(void **)(&uln) = dlsym(lib_handle, "uv_loop_new");
*(void **)(&ur) = dlsym(lib_handle, "uv_run");
*(void **)(&udl) = dlsym(lib_handle, "uv_default_loop");
*(void **)(&uii) = dlsym(lib_handle, "uv_idle_init");
*(void **)(&uist) = dlsym(lib_handle, "uv_idle_start");
*(void **)(&uisp) = dlsym(lib_handle, "uv_idle_stop");
uii(udl(), &idler);
uist(&idler, wait_for_a_while);
printf("Idling...\n");
ur(udl(), UV_RUN_DEFAULT);
dlclose(lib_handle);
// Code for static linking case
#else
uv_idle_init(uv_default_loop(), &idler);
uv_idle_start(&idler, wait_for_a_while);
printf("Idling...\n");
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
#endif
return 0;
}