From b593492d03dc722124ccee4989461a3eb608c305 Mon Sep 17 00:00:00 2001 From: Hans Oesterholt-Dijkema Date: Sun, 9 Jul 2006 17:10:05 +0000 Subject: * mzscheme code can now dynamically load libraries, that are needed at runtime. This allows for code to be generated at some site, and distributed without the need for SWIG. The distribution needs only the header filesfor which the code has been generated. Linking is done at runtime, by loading the dynamic libraries. Functions are resolved when needed. Though somewhat inefficient, it provides for a way to distribute code or binaries that are independent of the version of the installed libraries, which comes in especially handy for e.g. binding against Gtk. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@9211 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- .project | 11 +++ Lib/mzscheme/mzrun.swg | 194 ++++++++++++++++++++++++++++++++++++++++++++ Source/Modules/mzscheme.cxx | 59 +++++++++++++- 3 files changed, 260 insertions(+), 4 deletions(-) create mode 100644 .project diff --git a/.project b/.project new file mode 100644 index 000000000..86af75213 --- /dev/null +++ b/.project @@ -0,0 +1,11 @@ + + + SWIG + + + + + + + + diff --git a/Lib/mzscheme/mzrun.swg b/Lib/mzscheme/mzrun.swg index 52aa87aca..6a71fb79a 100644 --- a/Lib/mzscheme/mzrun.swg +++ b/Lib/mzscheme/mzrun.swg @@ -252,6 +252,199 @@ SWIG_MzScheme_new_scheme_struct (Scheme_Env* env, const char* basename, return new_type; } +/*** DLOPEN PATCH ****************************************************** + * Contributed by Hans Oesterholt-Dijkema (jan. 2006) + ***********************************************************************/ + +#if defined(_WIN32) || defined(__WIN32__) +#define __OS_WIN32 +#endif + +#ifdef __OS_WIN32 +#include +#else +#include +#endif + + static char **mz_dlopen_libraries=NULL; + static void **mz_libraries=NULL; + static char **mz_dynload_libpaths=NULL; + + static void mz_set_dlopen_libraries(const char *_libs) + { + int i,k,n; + int mz_dynload_debug=(1==0); + char *extra_paths[1000]; + char *EP; + + { + char *dbg=getenv("MZ_DYNLOAD_DEBUG"); + if (dbg!=NULL) { + mz_dynload_debug=atoi(dbg); + } + } + + { + char *ep=getenv("MZ_DYNLOAD_LIBPATH"); + int i,k,j; + k=0; + if (ep!=NULL) { + EP=strdup(ep); + for(i=0,j=0;EP[i]!='\0';i++) { + if (EP[i]==':') { + EP[i]='\0'; + extra_paths[k++]=&EP[j]; + j=i+1; + } + } + if (j!=i) { + extra_paths[k++]=&EP[j]; + } + } + else { + EP=strdup(""); + } + extra_paths[k]=NULL; + k+=1; + + if (mz_dynload_debug) { + fprintf(stderr,"SWIG:mzscheme:MZ_DYNLOAD_LIBPATH=%s\n",(ep==NULL) ? "(null)" : ep); + fprintf(stderr,"SWIG:mzscheme:extra_paths[%d]\n",k-1); + for(i=0;i %p\n",libp,mz_libraries[i]); + } + free(libp); + } + } + } + } + { + int i; + void *func=NULL; + + for(i=0;mz_dlopen_libraries[i]!=NULL && func==NULL;i++) { + if (mz_libraries[i]!=NULL) { +#ifdef __OS_WIN32 + func=GetProcAddress(mz_libraries[i],function); +#else + func=dlsym(mz_libraries[i],function); +#endif + } + if (mz_dynload_debug) { + fprintf(stderr, + "SWIG:mzscheme:library:%s;dlopen=%p,function=%s,func=%p\n", + mz_dlopen_libraries[i],mz_libraries[i],function,func + ); + } + } + + return func; + } + } + } + +/*** DLOPEN PATCH ****************************************************** + * Contributed by Hans Oesterholt-Dijkema (jan. 2006) + ***********************************************************************/ + /* The interpreter will store a pointer to this structure in a global variable called swig-runtime-data-type-pointer. The instance of this struct is only used if no other module has yet been loaded */ @@ -311,3 +504,4 @@ SWIG_MzScheme_SetModule(Scheme_Env *env, swig_module_info *module) { #ifdef __cplusplus } #endif + diff --git a/Source/Modules/mzscheme.cxx b/Source/Modules/mzscheme.cxx index e68bc0f6c..4085086df 100644 --- a/Source/Modules/mzscheme.cxx +++ b/Source/Modules/mzscheme.cxx @@ -15,10 +15,13 @@ char cvsroot_mzscheme_cxx[] = "$Header$"; static const char *usage = (char*)"\ Mzscheme Options (available with -mzscheme)\n\ - -prefix - Set a prefix to be prepended to all names\n\ - -declaremodule - Create extension that declares a module\n\ - -noinit - Do not emit scheme_initialize, scheme_reload,\n\ - scheme_module_name functions\n"; + -prefix - Set a prefix to be prepended to all names\n\ + -declaremodule - Create extension that declares a module\n\ + -noinit - Do not emit scheme_initialize, scheme_reload,\n\ + scheme_module_name functions\n\ + -dynamic-load ,[library,...] - Do not link with these libraries, dynamic load\n\ + them\n\ +"; static String *fieldnames_tab = 0; static String *convert_tab = 0; @@ -29,6 +32,9 @@ static String *mangled_struct_name = 0; static char *prefix=0; static bool declaremodule = false; static bool noinit = false; +//DLOPEN PATCH +static char *load_libraries = NULL; +//DLOPEN PATCH static String *module=0; static char *mzscheme_path=(char*)"mzscheme"; static String *init_func_def = 0; @@ -79,6 +85,14 @@ public: noinit = true; Swig_mark_arg (i); } +// DLOPEN PATCH + else if (strcmp(argv[i],"-dynamic-load") == 0) { + load_libraries=new char[strlen(argv[i+1])+2]; + strcpy(load_libraries,argv[i+1]); + Swig_mark_arg(i++); + Swig_mark_arg(i); + } +// DLOPEN PATCH } } @@ -153,6 +167,13 @@ public: } Printf (f_init, "\treturn scheme_void;\n}\n"); Printf(f_init, "Scheme_Object *scheme_initialize(Scheme_Env *env) {\n"); + + // DLOPEN PATCH + if (load_libraries) { + Printf(f_init,"mz_set_dlopen_libraries(\"%s\");\n",load_libraries); + } + // DLOPEN PATCH + Printf(f_init, "\treturn scheme_reload(env);\n"); Printf (f_init, "}\n"); @@ -217,6 +238,15 @@ public: int numreq; String *overname = 0; + // PATCH DLOPEN + if (load_libraries) { + ParmList *parms=Getattr(n,"parms"); + SwigType *type=Getattr(n,"type"); + String *name=NewString("caller"); + Setattr(n,"wrap:action", Swig_cresult(type,"result", Swig_cfunction_call(name,parms))); + } + // PATCH DLOPEN + // Make a wrapper name for this String *wname = Swig_name_wrapper(iname); if (Getattr(n,"sym:overloaded")) { @@ -255,11 +285,32 @@ public: numargs = emit_num_arguments(l); numreq = emit_num_required(l); + + // DLOPEN PATCH + /* Add the holder for the pointer to the function to be opened */ + if (load_libraries) { + Wrapper_add_local(f, "_function_loaded","static int _function_loaded=(1==0)"); + Wrapper_add_local(f, "_the_function", "static void *_the_function=NULL"); + { + String *parms=ParmList_protostr(l); + String *func=NewStringf("(*caller)(%s)",parms); + Wrapper_add_local(f,"caller",SwigType_lstr(d,func)); /*"(*caller)()"));*/ + } + } + // DLOPEN PATCH // adds local variables Wrapper_add_local(f, "lenv", "int lenv = 1"); Wrapper_add_local(f, "values", "Scheme_Object *values[MAXVALUES]"); + // DLOPEN PATCH + if (load_libraries) { + Printf(f->code,"if (!_function_loaded) { _the_function=mz_load_function(\"%s\");_function_loaded=(1==1); }\n",iname); + Printf(f->code,"if (!_the_function) { scheme_signal_error(\"Cannot load C function '%s'\"); }\n",iname); + Printf(f->code,"caller=_the_function;\n"); + } + // DLOPEN PATCH + // Now write code to extract the parameters (this is super ugly) for (i = 0, p = l; i < numargs; i++) { -- cgit v1.2.3