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 ADynamicLibrary* 39 adynamicLibrary_open( const char* libraryName, 40 char** pError) 41 { 42 char* libName = (char*) libraryName; 43 void* result; 44 45 /* Append a .dll to the library name if it doesn't have an extension */ 46 if (strchr(libraryName,'.') == NULL) { 47 libName = append_string(libraryName, ".dll"); 48 } 49 50 /* Now do our magic */ 51 *pError = NULL; 52 result = (ADynamicLibrary*) LoadLibrary( libName ); 53 if (result == NULL) { 54 *pError = ASTRDUP("Could not load DLL!"); 55 } 56 57 /* Free the library name if we modified it */ 58 if (libName != libraryName) { 59 free(libName); 60 } 61 62 return (ADynamicLibrary*) result; 63 } 64 65 void* 66 adynamicLibrary_findSymbol( ADynamicLibrary* lib, 67 const char* symbolName, 68 char** pError) 69 { 70 void* result; 71 72 *pError = NULL; 73 74 if (lib == NULL) { 75 *pError = strdup("NULL library pointer"); 76 return NULL; 77 } 78 if (symbolName == NULL || symbolName[0] == '\0') { 79 *pError = strdup("NULL or empty symbolName"); 80 return NULL; 81 } 82 result = GetProcAddress( (HMODULE)lib, symbolName ); 83 if (result == NULL) { 84 *pError = ASTRDUP("Could not find symbol"); 85 } 86 return result; 87 } 88 89 /* Close/unload a given dynamic library */ 90 void 91 adynamicLibrary_close( ADynamicLibrary* lib ) 92 { 93 if (lib != NULL) { 94 FreeLibrary( (HMODULE)lib ); 95 } 96 } 97 98 #else /* !_WIN32 */ 99 100 #include <dlfcn.h> 101 #include <stdlib.h> 102 103 ADynamicLibrary* 104 adynamicLibrary_open( const char* libraryName, 105 char** pError) 106 { 107 char* libName = (char*) libraryName; 108 void* result; 109 110 #ifdef __APPLE__ 111 # define SO_EXTENSION ".dylib" 112 #else 113 # define SO_EXTENSION ".so" 114 #endif 115 116 /* Append a .so to the library name if it doesn't have an extension */ 117 if (strchr(libraryName,'.') == NULL) { 118 libName = append_string(libraryName, SO_EXTENSION); 119 } 120 121 /* Now do our magic */ 122 *pError = NULL; 123 result = dlopen( libName, RTLD_LAZY ); 124 if (result == NULL) { 125 *pError = strdup(dlerror()); 126 } 127 128 /* Free the library name if we modified it */ 129 if (libName != (char*)libraryName) { 130 free(libName); 131 } 132 133 return (ADynamicLibrary*) result; 134 } 135 136 void* 137 adynamicLibrary_findSymbol( ADynamicLibrary* lib, 138 const char* symbolName, 139 char** pError) 140 { 141 void* result; 142 143 *pError = NULL; 144 145 if (lib == NULL) { 146 *pError = strdup("NULL library pointer"); 147 return NULL; 148 } 149 if (symbolName == NULL || symbolName[0] == '\0') { 150 *pError = strdup("NULL or empty symbolName"); 151 return NULL; 152 } 153 result = dlsym(lib, symbolName); 154 if (result == NULL) { 155 *pError = strdup(dlerror()); 156 } 157 return result; 158 } 159 160 /* Close/unload a given dynamic library */ 161 void 162 adynamicLibrary_close( ADynamicLibrary* lib ) 163 { 164 if (lib != NULL) { 165 dlclose(lib); 166 } 167 } 168 169 #endif /* !_WIN32 */ 170