diff --git a/api/graphics_impl.h b/api/graphics_impl.h index 15699e4806..190714d33e 100644 --- a/api/graphics_impl.h +++ b/api/graphics_impl.h @@ -23,8 +23,16 @@ extern int boinc_init_graphics_impl( void (*worker)(), int (*init_func)(BOINC_OPTIONS&) ); -extern int boinc_init_options_graphics_impl( +// This extern C is needed, even to make this code work correctly on a 100% C++ +// platoform, app, and build. This is because we need to dlsym() resolve this +// function. That does not work unless the symbol is in the library in UNMANGED +// form. See http://www.isotton.com/howtos/C++-dlopen-mini-HOWTO/C++-dlopen-mini-HOWTO.html +// for some additional discussion. + +extern "C" { + int boinc_init_options_graphics_impl( BOINC_OPTIONS& opt, void (*_worker_main)(), int (*init_func)(BOINC_OPTIONS&) ); +} diff --git a/api/graphics_lib.C b/api/graphics_lib.C index 2e0cea407f..bae954c94d 100644 --- a/api/graphics_lib.C +++ b/api/graphics_lib.C @@ -81,7 +81,10 @@ int boinc_init_options_graphics_lib( goto no_graphics; } - // get handle for shared library + // get handle for shared library. Note that this handle is a + // global variable, so it can be declared 'extern' in worker() and + // thus worker() has access to functions from within this shared + // library, also. // graphics_lib_handle = dlopen(resolved_name, RTLD_NOW); if (!graphics_lib_handle) { @@ -92,6 +95,9 @@ int boinc_init_options_graphics_lib( goto no_graphics; } + // use handle from shared library to resolve the 'initialize + // graphics' routine from shared library + // boinc_init_options_graphics_impl_hook = (BIOGI_FUNC) dlsym( graphics_lib_handle, "boinc_init_options_graphics_impl" @@ -99,12 +105,15 @@ int boinc_init_options_graphics_lib( if (!boinc_init_options_graphics_impl_hook) { errormsg = dlerror(); fprintf(stderr, - "dlsym() couldn't find boinc_init_options_graphics_impl in %s\n", - resolved_name + "dlsym(): no boinc_init_options_graphics_impl() in %s\n%s\n", + resolved_name, errormsg?errormsg:"" ); goto no_graphics; } + // here's where we start the graphics thread and the worker + // thread. Normally this function should not return. + // retval = boinc_init_options_graphics_impl_hook( opt, worker, boinc_init_options_general ); @@ -117,10 +126,13 @@ int boinc_init_options_graphics_lib( } boinc_finish(retval); - + // never get here... + return 1; + no_graphics: // unable to resolve the shared object file, or unable to resolve - // dependencies on machine, or unable to find needed symbol in library + // library dependencies on machine (eg, no X11, no GL libraries, + // etc) or unable to find needed symbol in library // boinc_init_options(opt); worker(); @@ -128,6 +140,6 @@ no_graphics: // worker() should call boinc_finish so we should NEVER get here! // boinc_finish(1); + // never get here... return 1; } - diff --git a/checkin_notes b/checkin_notes index bfc1e6d161..8850a66b8c 100755 --- a/checkin_notes +++ b/checkin_notes @@ -21138,3 +21138,20 @@ David 11 Dec 2004 api/ Makefile.am + +Bruce 12 Dec 2004 + Added extern C declarations to a couple of header files: + - In graphics_lib.h, this is for compatibility with pure C + applications. + - In graphics_impl.h, this would be needed EVEN if we were + never building app or library with anything other than C++. + It's because dlsym() can only work if you pass it a non-name + mangled symbol. Please see: + http://www.isotton.com/howtos/C++-dlopen-mini-HOWTO/C++-dlopen-mini-HOWTO.html + for futher edetail. + - Comments added to graphics_lib.C, better error message. + + api/ + graphics_lib.C + graphics_lib.h + graphics_impl.h