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 */ 19static char* 20append_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 38ADynamicLibrary* 39adynamicLibrary_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 65void* 66adynamicLibrary_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 */ 90void 91adynamicLibrary_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 103ADynamicLibrary* 104adynamicLibrary_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 136void* 137adynamicLibrary_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 */ 161void 162adynamicLibrary_close( ADynamicLibrary* lib ) 163{ 164 if (lib != NULL) { 165 dlclose(lib); 166 } 167} 168 169#endif /* !_WIN32 */ 170