Home | History | Annotate | Download | only in utils
      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