6 ex_module_8c example
gullradriel edited this page 2026-10-09 00:55:18 +02:00

ex_module.c

open a shared library at runtime, find a symbol, call it Opens the system maths library (kernel32 on Windows), finds a function in it and calls it, then checks the failures: a library that is not there, a symbol the library does not have, and closing twice. Each failure must leave a reason in n_module_error(). ```c

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h>

#include "nilorea/n_common.h" #include "nilorea/n_log.h" #include "nilorea/n_module.h"

#if defined(windows) #define EX_LIBRARY "kernel32.dll" #define EX_SYMBOL "GetTickCount" #elif defined(APPLE) #define EX_LIBRARY "libSystem.dylib" #define EX_SYMBOL "cos" #else #define EX_LIBRARY "libm.so.6" #define EX_SYMBOL "cos" #endif

static int log_level = LOG_ERR; static int failures = 0;

static void expect_true(const char* what, int ok) { if (!ok) { n_log(LOG_ERR, "FAIL: %s", what); failures++; } else { n_log(LOG_INFO, "ok: %s", what); } }

static int parse_args(int argc, char** argv) { int opt = 0;

while ((opt = getopt(argc, argv, "V:")) != -1) {
    if (opt == 'V') {
        log_level = atoi(optarg);
    } else {
        return -1;
    }
}
return 0;

}

int main(int argc, char** argv) { N_MODULE* module = NULL; void* symbol = NULL;

set_log_level(LOG_ERR);
if (parse_args(argc, argv) != 0) {
    fprintf(stderr, "usage: %s [-V LOGLEVEL]\n", argv[0]);
    return 2;
}
set_log_level(log_level);

expect_true("the extension is not empty", n_module_extension()[0] != '\0');
expect_true("no error before any call", n_module_error()[0] == '\0');

module = n_module_open(EX_LIBRARY);
expect_true("the system library opens", module != NULL);
if (module) {
    symbol = n_module_symbol(module, EX_SYMBOL);
    expect_true("its function is found", symbol != NULL);

#if !defined(windows) if (symbol) { double (*fn)(double) = NULL;

        memcpy((void*)&fn, (const void*)&symbol, sizeof(fn));
        expect_true("calling it gives cos(0) = 1", fn(0.0) == 1.0);
    }

#endif expect_true("a missing symbol is NULL", n_module_symbol(module, "n_module_no_such_symbol") == NULL); expect_true("and says why", n_module_error()[0] != '\0'); expect_true("a found symbol clears the error", n_module_symbol(module, EX_SYMBOL) != NULL && n_module_error()[0] == '\0'); expect_true("close succeeds", n_module_close(&module) == TRUE); expect_true("close sets the handle to NULL", module == NULL); } expect_true("closing NULL is a no-op", n_module_close(&module) == TRUE); expect_true("closing a NULL address is a no-op", n_module_close(NULL) == TRUE);

module = n_module_open("n_module_no_such_library.so");
expect_true("a missing library is NULL", module == NULL);
expect_true("and says why", n_module_error()[0] != '\0');
n_log(LOG_INFO, "the reason given: %s", n_module_error());

if (failures) {
    n_log(LOG_ERR, "%d check(s) failed", failures);
    return 1;
}
n_log(LOG_NOTICE, "all module checks passed");
return 0;

}


_Filename: ex_module.c_