#include #include #include #define LIBGPS_PATH "./gpsd/libgps.so" #define LIBGPSD_PATH "./gpsd/libgpsd.so" #include "gpsd/gpsd.h" /* * Each application used to be forced to define these two entry points, * so most of them just copied gpsd.c's. This is no longer necessary. */ #if 0 ssize_t gpsd_write(struct gps_device_t *session, const char *buf, const size_t len) /* pass low-level data to devices straight through */ { return gpsd_serial_write(session, buf, len); } void gpsd_report(const int debuglevel, const int errlevel, const char *fmt, ...) { va_list ap; va_start(ap, fmt); gpsd_labeled_report(debuglevel, errlevel, "gpsd:", fmt, ap); va_end(ap); } #endif /* end gpsd.c copy'n'pasta */ int main(int argc, char **argv) { void *libgps; void *libgpsd; int flags = // No effect on behaviour RTLD_LAZY /* Necessary so that libgps's symbols will be available to libgpsd. * * libgpsd depends on libgps's symbols, but is not explicitly * linked against libgps. Therefore the dynamic linker will not * automatically load libgps when loading libgpsd. * So we need to help the dynamic linker, by (in order): * 1. Loading libgps with RTLD_GLOBAL, so that its symbols will be * available to libraries loaded later on, such as libgpsd, then * 2. Loading libgpsd. */ | RTLD_GLOBAL ; libgps = dlopen(LIBGPS_PATH, flags); if (NULL == libgps) { fprintf(stderr, "Failed to load libgps from " LIBGPS_PATH ": %s\n", dlerror()); return EXIT_FAILURE; } puts("Loaded libgps from " LIBGPS_PATH); libgpsd = dlopen(LIBGPSD_PATH, flags); if (NULL == libgpsd) { fprintf(stderr, "Failed to load libgpsd from " LIBGPSD_PATH ": %s\n", dlerror()); return EXIT_FAILURE; } puts("Loaded libgpsd from " LIBGPSD_PATH); if (0 != dlclose(libgpsd)) { fprintf(stderr, "Failed to unload libgpsd: %s\n", dlerror()); return EXIT_FAILURE; } puts("Unloaded libgpsd"); if (0 != dlclose(libgps)) { fprintf(stderr, "Failed to unload libgps: %s\n", dlerror()); return EXIT_FAILURE; } puts("Unloaded libgps"); return EXIT_SUCCESS; }