Does libjulia support dynamic reinitialization?

I need a dynamic Julia re-initialization but I guess it’s not supported or there is a bug in the libjulia because in the example below variable x keeps it’s previous value after second jl_init call.

#include <julia.h>
#include <stdio.h>

int64_t getX() {
  jl_value_t *x = jl_eval_string("x");
  return jl_unbox_int64(x);
}

int main(int argc, char *argv[]) {

  jl_init();

  jl_eval_string("x::Int64 = 19");

  printf("x: %d\n", getX());

  jl_atexit_hook(0);

  jl_init();

  jl_eval_string("x=x+1");

  printf("x: %d\n", getX());

  jl_atexit_hook(0);

  return 0;
}

Output:
x: 19
x: 20

Have you considered dynamically loading libjulia.so and then unloading the shared library via dlopen and then dlclose?

@GunnarFarneback has an example here:

I’m not completely sure this is supported, but this would be my best guess.

1 Like

I have considered to use dlopen/dlclose but it would be better to have more convenient option to work with the library. Anyway thank you for example, it can be useful for me.

This is more developed if you want to look into dynamically loading libjulia: GitHub - GunnarFarneback/DynamicallyLoadedEmbedding.jl: Embed Julia with dynamical loading of libjulia at runtime.

Unfortunately dynamic library loading/unloading gives the same result :frowning_face:

#include <stdint.h>
#include <stdio.h>
#include <windows.h>

#define JULIA_LIB                                                              \
  "Julia-1.9.4\\bin\\libjulia."    \
  "dll"

HMODULE libjulia;

#define JL_NOTSAFEPOINT

typedef struct _jl_value_t jl_value_t;
typedef struct _jl_sym_t jl_sym_t;
typedef struct _jl_module_t jl_module_t;
typedef jl_value_t jl_function_t;

static void (*jl_init)(void);
static void (*jl_atexit_hook)(int);
static jl_value_t *(*jl_eval_string)(const char *);
static int64_t (*jl_unbox_int64)(jl_value_t *v) JL_NOTSAFEPOINT;

static void *load_function(const char *name, int *success) {
  void *p = GetProcAddress(libjulia, name);

  if (!p) {
    fprintf(stderr, "%s not found in libjulia.\n", name);
    *success = 0;
  }

  return p;
}

void julia_init() {
  libjulia = LoadLibrary(JULIA_LIB);
  if (libjulia == NULL) {
    fprintf(stderr, "libjulia isn't found.\n");
    exit(1);
  }
  int success = 1;
  jl_init = load_function("jl_init", &success);
  jl_atexit_hook = load_function("jl_atexit_hook", &success);
  jl_eval_string = load_function("jl_eval_string", &success);
  jl_unbox_int64 = load_function("jl_unbox_int64", &success);

  if (!success) {
    fprintf(stderr, "libjulia intialization failed.\n");
  }

  jl_init();
}

void julia_deinit() {
  jl_atexit_hook(0);
  BOOL res = FreeLibrary(libjulia);
  if (res == FALSE) {
    fprintf(stderr, "libjulia library unloading failure.\n");
  }
}

int64_t getX() {
  jl_value_t *x = jl_eval_string("x");
  return jl_unbox_int64(x);
}

int main(int argc, char *argv[]) {

  julia_init();

  jl_eval_string("x::Int64 = 19");

  printf("x: %lld\n", getX());

  julia_deinit();

  julia_init();

  jl_eval_string("x=x+1");

  printf("x: %lld\n", getX());

  julia_deinit();

  return 0;
}

x: 19
x: 20