@needs_dlfcn
def test_dlfcn_data_and_fptr(self):
    if self.is_wasm():
        self.banned_js_engines = [V8_ENGINE]
    self.prep_dlfcn_lib()
    lib_src = '\n      #include <stdio.h>\n\n      int theglobal = 42;\n\n      extern void parent_func(); // a function that is defined in the parent\n\n      int* lib_get_global_addr() {\n        return &theglobal;\n      }\n\n      void lib_fptr() {\n        printf("Second calling lib_fptr from main.\\n");\n        parent_func();\n        // call it also through a pointer, to check indexizing\n        void (*p_f)();\n        p_f = parent_func;\n        p_f();\n      }\n\n      extern "C" void (*func(int x, void(*fptr)()))() {\n        printf("In func: %d\\n", x);\n        fptr();\n        return lib_fptr;\n      }\n      '
    dirname = self.get_dir()
    filename = os.path.join(dirname, 'liblib.cpp')
    self.set_setting('EXPORTED_FUNCTIONS', ['_func'])
    self.build_dlfcn_lib(lib_src, dirname, filename)
    self.prep_dlfcn_main()
    src = '\n      #include <stdio.h>\n      #include <dlfcn.h>\n      #include <emscripten.h>\n\n      typedef void (*FUNCTYPE(int, void(*)()))();\n\n      FUNCTYPE func;\n\n      void EMSCRIPTEN_KEEPALIVE parent_func() {\n        printf("parent_func called from child\\n");\n      }\n\n      void main_fptr() {\n        printf("First calling main_fptr from lib.\\n");\n      }\n\n      int main() {\n        void* lib_handle;\n        FUNCTYPE* func_fptr;\n\n        // Test basic lib loading.\n        lib_handle = dlopen("liblib.so", RTLD_NOW);\n        if (lib_handle == NULL) {\n          printf("Could not load lib.\\n");\n          return 1;\n        }\n\n        // Test looked up function.\n        func_fptr = (FUNCTYPE*) dlsym(lib_handle, "func");\n        // Load twice to test cache.\n        func_fptr = (FUNCTYPE*) dlsym(lib_handle, "func");\n        if (func_fptr == NULL) {\n          printf("Could not find func.\\n");\n          return 1;\n        }\n\n        // Test passing function pointers across module bounds.\n        void (*fptr)() = func_fptr(13, main_fptr);\n        fptr();\n\n        // Test global data.\n        int* globaladdr = (int*) dlsym(lib_handle, "theglobal");\n        if (globaladdr == NULL) {\n          printf("Could not find global.\\n");\n          return 1;\n        }\n\n        printf("Var: %d\\n", *globaladdr);\n\n        return 0;\n      }\n      '
    self.set_setting('EXPORTED_FUNCTIONS', ['_main'])
    self.do_run(src, 'In func: 13\nFirst calling main_fptr from lib.\nSecond calling lib_fptr from main.\nparent_func called from child\nparent_func called from child\nVar: 42\n')
@needs_dlfcn
def test_dlfcn_data_and_fptr(self):
    if self.is_wasm():
        self.banned_js_engines = [V8_ENGINE]
    self.prep_dlfcn_lib()
    lib_src = '\n      #include <stdio.h>\n\n      int theglobal = 42;\n\n      extern void parent_func(); // a function that is defined in the parent\n\n      int* lib_get_global_addr() {\n        return &theglobal;\n      }\n\n      void lib_fptr() {\n        printf("Second calling lib_fptr from main.\\n");\n        parent_func();\n        // call it also through a pointer, to check indexizing\n        void (*p_f)();\n        p_f = parent_func;\n        p_f();\n      }\n\n      extern "C" void (*func(int x, void(*fptr)()))() {\n        printf("In func: %d\\n", x);\n        fptr();\n        return lib_fptr;\n      }\n      '
    dirname = self.get_dir()
    filename = os.path.join(dirname, 'liblib.cpp')
    self.set_setting('EXPORTED_FUNCTIONS', ['_func'])
    self.build_dlfcn_lib(lib_src, dirname, filename)
    self.prep_dlfcn_main()
    src = '\n      #include <stdio.h>\n      #include <dlfcn.h>\n      #include <emscripten.h>\n\n      typedef void (*FUNCTYPE(int, void(*)()))();\n\n      FUNCTYPE func;\n\n      void EMSCRIPTEN_KEEPALIVE parent_func() {\n        printf("parent_func called from child\\n");\n      }\n\n      void main_fptr() {\n        printf("First calling main_fptr from lib.\\n");\n      }\n\n      int main() {\n        void* lib_handle;\n        FUNCTYPE* func_fptr;\n\n        // Test basic lib loading.\n        lib_handle = dlopen("liblib.so", RTLD_NOW);\n        if (lib_handle == NULL) {\n          printf("Could not load lib.\\n");\n          return 1;\n        }\n\n        // Test looked up function.\n        func_fptr = (FUNCTYPE*) dlsym(lib_handle, "func");\n        // Load twice to test cache.\n        func_fptr = (FUNCTYPE*) dlsym(lib_handle, "func");\n        if (func_fptr == NULL) {\n          printf("Could not find func.\\n");\n          return 1;\n        }\n\n        // Test passing function pointers across module bounds.\n        void (*fptr)() = func_fptr(13, main_fptr);\n        fptr();\n\n        // Test global data.\n        int* globaladdr = (int*) dlsym(lib_handle, "theglobal");\n        if (globaladdr == NULL) {\n          printf("Could not find global.\\n");\n          return 1;\n        }\n\n        printf("Var: %d\\n", *globaladdr);\n\n        return 0;\n      }\n      '
    self.set_setting('EXPORTED_FUNCTIONS', ['_main'])
    self.do_run(src, 'In func: 13\nFirst calling main_fptr from lib.\nSecond calling lib_fptr from main.\nparent_func called from child\nparent_func called from child\nVar: 42\n')