1/* Copyright (c) 2008 The Android Open Source Project 2 * 3 * Permission is hereby granted, free of charge, to any person obtaining a copy 4 * of this software and associated documentation files (the "Software"), to deal 5 * in the Software without restriction, including without limitation the rights 6 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 * copies of the Software, and to permit persons to whom the Software is 8 * furnished to do so, subject to the following conditions: 9 * 10 * The above copyright notice and this permission notice shall be included in 11 * all copies or substantial portions of the Software. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 16 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 * THE SOFTWARE. 20 */ 21 22/* 23 * Lazy Dynamic Linking Support 24 * 25 * This header file is meant to be included multiple times. 26 * 27 * It is used to define function pointers to symbols in external 28 * shared objects (Unix dynamic libraries) which will be lazily resolved 29 * at runtime, by calling a specific initialization function. 30 * 31 * You must define, before including this header, a DYNLINK_FUNCTIONS 32 * macro which must contain a sequence of DYNLINK_FUNC(ret,name,sig) 33 * statements. 34 * 35 * In each statement, 'ret' is a function return type, 'name' is 36 * the function's name as provided by the library, and 'sig' is 37 * the function signature, including enclosing parentheses. 38 * 39 * Here's an example: 40 * 41 * #define DYNLINK_FUNCTIONS \ 42 * DYNLINK_FUNC(int,open,(const char*, int)) \ 43 * DYNLINK_FUNC(int,read,(int,char*,int)) \ 44 * DYNLINK_FUNC(int,close,(int)) \ 45 * 46 * 47 * You must also define a DYNLINK_FUNCTIONS_INIT macro which contains the 48 * name of a generated function used to initialize the function pointers. 49 * (see below) 50 */ 51 52#ifndef DYNLINK_FUNCTIONS 53#error DYNLINK_FUNCTIONS should be defined when including this file 54#endif 55 56#ifndef DYNLINK_FUNCTIONS_INIT 57#error DYNLINK_FUNCTIONS_INIT should be defined when including this file 58#endif 59 60/* just in case */ 61#undef DYNLINK_FUNC 62 63/* define pointers to dynamic library functions as static pointers. 64 */ 65#define DYNLINK_FUNC(ret,name,sig) \ 66 static ret (*_dynlink_##name) sig ; 67 68#define DYNLINK_STR(name) DYNLINK_STR_(name) 69#define DYNLINK_STR_(name) #name 70 71DYNLINK_FUNCTIONS 72#undef DYNLINK_FUNC 73 74/* now define a function that tries to load all dynlink function 75 * pointers. returns 0 on success, or -1 on error (i.e. if any of 76 * the functions could not be loaded). 77 * 78 * 'library' must be the result of a succesful dlopen() call 79 * 80 * You must define DYNLINK_FUNCTIONS_INIT 81 */ 82static int 83DYNLINK_FUNCTIONS_INIT(void* library) 84{ 85#define DYNLINK_FUNC(ret,name,sig) \ 86 do { \ 87 _dynlink_##name = dlsym( library, DYNLINK_STR(name) ); \ 88 if (_dynlink_##name == NULL) goto Fail; \ 89 } while (0); 90 91 DYNLINK_FUNCTIONS 92#undef DYNLINK_FUNC 93 94 return 0; 95Fail: 96 return -1; 97} 98 99/* in user code, use FF(function_name) to invoke the 100 * corresponding dynamic function named 'function_name' 101 * after initialization succeeded. 102 */ 103#ifndef FF 104#define FF(name) (*_dynlink_##name) 105#endif 106 107/* clear macros */ 108#undef DYNLINK_FUNC 109#undef DYNLINK_FUNCTIONS 110#undef DYNLINK_FUNCTIONS_INIT 111