00001 #ifndef DYNAMIC_LOADER_IMPLEMENTATION_FILE 00002 #define DYNAMIC_LOADER_IMPLEMENTATION_FILE 00003 00004 /*****************************************************************************\ 00005 * * 00006 * Name : dynamic_library_loader * 00007 * Author : Chris Koeritz * 00008 * * 00009 ******************************************************************************* 00010 * Copyright (c) 1998-$now By Author. This program is free software; you can * 00011 * redistribute it and/or modify it under the terms of the GNU General Public * 00012 * License as published by the Free Software Foundation; either version 2 of * 00013 * the License or (at your option) any later version. This is online at: * 00014 * http://www.fsf.org/copyleft/gpl.html * 00015 * Please send any updates to: fred@gruntose.com * 00016 \*****************************************************************************/ 00017 00018 #include "dynamic_loader.h" 00019 #include "virtual_library.h" 00020 00021 #include <basis/convert_utf.h> 00022 #include <basis/function.h> 00023 #include <basis/istring.h> 00024 #include <basis/portable.h> 00025 00026 #ifdef __LINUX__ 00027 #include <dlfcn.h> 00028 #endif 00029 00030 namespace library_plugins { 00031 00032 typedef virtual_library *creation_function(vl_data_pack ¶meters); 00033 // a handy prototype that allows one to refer to the instance function. 00034 00035 dynamic_library_loader::dynamic_library_loader(const istring &dll_name, 00036 bool load_it) 00037 : _dll_name(new istring(dll_name)), 00038 _dll_handle(NIL) 00039 { 00040 // we can't load the _dll_handle in the initialization phase above since 00041 // we don't have a valid virtual function table yet. this is definitely 00042 // a concern for derived versions also; they should always pass false for 00043 // the "load_it" flag. 00044 00045 if (load_it) load_the_library(); 00046 } 00047 00048 bool dynamic_library_loader::load_the_library() 00049 { 00050 _dll_handle = load_library(_dll_name->s()); 00051 return !!_dll_handle; 00052 } 00053 00054 dynamic_library_loader::~dynamic_library_loader() 00055 { 00056 if (_dll_handle) { 00057 free_library(_dll_handle); 00058 _dll_handle = NIL; 00059 } 00060 WHACK(_dll_name); 00061 } 00062 00063 const istring &dynamic_library_loader::dll_name() const { return *_dll_name; } 00064 00065 bool dynamic_library_loader::loaded() const { return !!_dll_handle; } 00066 00067 void *dynamic_library_loader::load_library(const char *to_load) 00068 { 00069 #ifdef __WIN32__ 00070 void *to_return = LoadLibrary(to_unicode_temp(to_load)); 00071 if (to_return <= (void *)HINSTANCE_ERROR) to_return = NIL; 00072 return to_return; 00073 #else 00074 return dlopen(to_load, RTLD_NOW); 00075 #endif 00076 } 00077 00078 void dynamic_library_loader::free_library(void *to_free) 00079 { 00080 #ifdef __WIN32__ 00081 FreeLibrary((application_instance)to_free); 00082 #else 00083 dlclose(to_free); 00084 #endif 00085 } 00086 00087 union dlsym_hack { 00088 void *ptr_version; 00089 dynamic_library_loader::shared_method *func_version; 00090 }; 00091 00092 dynamic_library_loader::shared_method *dynamic_library_loader::load_method 00093 (void *dll_handle, const char *method_name) 00094 { 00095 dynamic_library_loader::shared_method *to_return = NIL; 00096 #ifdef __WIN32__ 00097 to_return = (dynamic_library_loader::shared_method *) 00098 GetProcAddress((application_instance)dll_handle, method_name); 00099 #else 00100 dlsym_hack temp; 00101 temp.ptr_version = dlsym(dll_handle, method_name); 00102 to_return = temp.func_version; 00103 #endif 00104 return to_return; 00105 } 00106 00107 virtual_library *dynamic_library_loader::create(vl_data_pack ¶meters) 00108 { 00109 if (!loaded()) return NIL; // couldn't find the DLL originally. 00110 creation_function *creater = (creation_function *)load_method(_dll_handle, 00111 STATIC_CREATE_INSTANCE_NAME); 00112 if (!creater) return NIL; // couldn't locate the required function. 00113 return creater(parameters); 00114 } 00115 00116 } // namespace. 00117 00118 00119 #endif //DYNAMIC_LOADER_IMPLEMENTATION_FILE 00120
1.5.1