1 /* Copyright (C) 2011 The Android Open Source Project 2 ** 3 ** This software is licensed under the terms of the GNU General Public 4 ** License version 2, as published by the Free Software Foundation, and 5 ** may be copied, distributed, and modified under those terms. 6 ** 7 ** This program is distributed in the hope that it will be useful, 8 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 9 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 ** GNU General Public License for more details. 11 */ 12 #include <android/utils/dll.h> 13 #include <android/utils/system.h> 14 #include <android/utils/path.h> 15 16 #include <stdlib.h> 17 18 /* Utility function, append one string to another, caller must free result */ 19 static char* 20 append_string( const char* str1, const char* str2 ) 21 { 22 int len1 = strlen(str1); 23 int len2 = strlen(str2); 24 char* result = malloc(len1+len2+1); 25 26 if (result != NULL) { 27 memcpy(result, str1, len1); 28 memcpy(result + len1, str2, len2); 29 result[len1+len2] = '\0'; 30 } 31 return result; 32 } 33 34 #ifdef _WIN32 35 36 #include <windows.h> 37 38 /* This function is used to revert all forward slashes (/) in a path 39 * string into unquoted backwards one (\). This is necessary because 40 * LoadLibrary() and AddDllDirectory() do not support forward slashes. 41 * 42 * Caller must free the result string 43 */ 44 static char* 45 reverse_slashes( const char* path ) 46 { 47 int len = strlen(path); 48 char* result = malloc(len+1); 49 int nn; 50 51 for (nn = 0; nn < len; nn++) { 52 int ch = path[nn]; 53 if (ch == '/') { 54 ch = '\\'; 55 } 56 result[nn] = (char)ch; 57 } 58 result[nn] = '\0'; 59 60 return result; 61 } 62 63 ADynamicLibrary* 64 adynamicLibrary_open( const char* libraryName, 65 char** pError) 66 { 67 char* libName = (char*) libraryName; 68 void* result; 69 70 /* Append a .dll to the library name if it doesn't have an extension */ 71 if (strchr(libraryName,'.') == NULL) { 72 libName = append_string(libraryName, ".dll"); 73 } 74 75 /* Now do our magic */ 76 *pError = NULL; 77 result = (ADynamicLibrary*) LoadLibrary( libName ); 78 if (result == NULL) { 79 *pError = ASTRDUP("Could not load DLL!"); 80 } 81 82 /* Free the library name if we modified it */ 83 if (libName != libraryName) { 84 free(libName); 85 } 86 87 return (ADynamicLibrary*) result; 88 } 89 90 void* 91 adynamicLibrary_findSymbol( ADynamicLibrary* lib, 92 const char* symbolName, 93 char** pError) 94 { 95 void* result; 96 97 *pError = NULL; 98 99 if (lib == NULL) { 100 *pError = strdup("NULL library pointer"); 101 return NULL; 102 } 103 if (symbolName == NULL || symbolName[0] == '\0') { 104 *pError = strdup("NULL or empty symbolName"); 105 return NULL; 106 } 107 result = GetProcAddress( (HMODULE)lib, symbolName ); 108 if (result == NULL) { 109 *pError = ASTRDUP("Could not find symbol"); 110 } 111 return result; 112 } 113 114 /* Close/unload a given dynamic library */ 115 void 116 adynamicLibrary_close( ADynamicLibrary* lib ) 117 { 118 if (lib != NULL) { 119 FreeLibrary( (HMODULE)lib ); 120 } 121 } 122 123 #else /* !_WIN32 */ 124 125 #include <dlfcn.h> 126 #include <stdlib.h> 127 128 ADynamicLibrary* 129 adynamicLibrary_open( const char* libraryName, 130 char** pError) 131 { 132 char* libName = (char*) libraryName; 133 void* result; 134 135 #ifdef __APPLE__ 136 # define SO_EXTENSION ".dylib" 137 #else 138 # define SO_EXTENSION ".so" 139 #endif 140 141 /* Append a .so to the library name if it doesn't have an extension */ 142 if (strchr(libraryName,'.') == NULL) { 143 libName = append_string(libraryName, SO_EXTENSION); 144 } 145 146 /* Now do our magic */ 147 *pError = NULL; 148 result = dlopen( libName, RTLD_LAZY ); 149 if (result == NULL) { 150 *pError = strdup(dlerror()); 151 } 152 153 /* Free the library name if we modified it */ 154 if (libName != (char*)libraryName) { 155 free(libName); 156 } 157 158 return (ADynamicLibrary*) result; 159 } 160 161 void* 162 adynamicLibrary_findSymbol( ADynamicLibrary* lib, 163 const char* symbolName, 164 char** pError) 165 { 166 void* result; 167 168 *pError = NULL; 169 170 if (lib == NULL) { 171 *pError = strdup("NULL library pointer"); 172 return NULL; 173 } 174 if (symbolName == NULL || symbolName[0] == '\0') { 175 *pError = strdup("NULL or empty symbolName"); 176 return NULL; 177 } 178 result = dlsym(lib, symbolName); 179 if (result == NULL) { 180 *pError = strdup(dlerror()); 181 } 182 return result; 183 } 184 185 /* Close/unload a given dynamic library */ 186 void 187 adynamicLibrary_close( ADynamicLibrary* lib ) 188 { 189 if (lib != NULL) { 190 dlclose(lib); 191 } 192 } 193 194 #endif /* !_WIN32 */ 195