1 : /******************************************************************************
2 : * $Id: cplgetsymbol.cpp 16702 2009-04-01 20:42:49Z rouault $
3 : *
4 : * Project: Common Portability Library
5 : * Purpose: Fetch a function pointer from a shared library / DLL.
6 : * Author: Frank Warmerdam, warmerdam@pobox.com
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 1999, Frank Warmerdam
10 : *
11 : * Permission is hereby granted, free of charge, to any person obtaining a
12 : * copy of this software and associated documentation files (the "Software"),
13 : * to deal in the Software without restriction, including without limitation
14 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 : * and/or sell copies of the Software, and to permit persons to whom the
16 : * Software is furnished to do so, subject to the following conditions:
17 : *
18 : * The above copyright notice and this permission notice shall be included
19 : * in all copies or substantial portions of the Software.
20 : *
21 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 : * DEALINGS IN THE SOFTWARE.
28 : ****************************************************************************/
29 :
30 : #include "cpl_conv.h"
31 :
32 : CPL_CVSID("$Id: cplgetsymbol.cpp 16702 2009-04-01 20:42:49Z rouault $");
33 :
34 :
35 : /* ==================================================================== */
36 : /* Unix Implementation */
37 : /* ==================================================================== */
38 :
39 : /* MinGW32 might define HAVE_DLFCN_H, so skip the unix implementation */
40 : #if defined(HAVE_DLFCN_H) && !defined(WIN32)
41 :
42 : #define GOT_GETSYMBOL
43 :
44 : #include <dlfcn.h>
45 :
46 : /************************************************************************/
47 : /* CPLGetSymbol() */
48 : /************************************************************************/
49 :
50 : /**
51 : * Fetch a function pointer from a shared library / DLL.
52 : *
53 : * This function is meant to abstract access to shared libraries and
54 : * DLLs and performs functions similar to dlopen()/dlsym() on Unix and
55 : * LoadLibrary() / GetProcAddress() on Windows.
56 : *
57 : * If no support for loading entry points from a shared library is available
58 : * this function will always return NULL. Rules on when this function
59 : * issues a CPLError() or not are not currently well defined, and will have
60 : * to be resolved in the future.
61 : *
62 : * Currently CPLGetSymbol() doesn't try to:
63 : * <ul>
64 : * <li> prevent the reference count on the library from going up
65 : * for every request, or given any opportunity to unload
66 : * the library.
67 : * <li> Attempt to look for the library in non-standard
68 : * locations.
69 : * <li> Attempt to try variations on the symbol name, like
70 : * pre-prending or post-pending an underscore.
71 : * </ul>
72 : *
73 : * Some of these issues may be worked on in the future.
74 : *
75 : * @param pszLibrary the name of the shared library or DLL containing
76 : * the function. May contain path to file. If not system supplies search
77 : * paths will be used.
78 : * @param pszSymbolName the name of the function to fetch a pointer to.
79 : * @return A pointer to the function if found, or NULL if the function isn't
80 : * found, or the shared library can't be loaded.
81 : */
82 :
83 336 : void *CPLGetSymbol( const char * pszLibrary, const char * pszSymbolName )
84 :
85 : {
86 : void *pLibrary;
87 : void *pSymbol;
88 :
89 336 : pLibrary = dlopen(pszLibrary, RTLD_LAZY);
90 336 : if( pLibrary == NULL )
91 : {
92 : CPLError( CE_Failure, CPLE_AppDefined,
93 0 : "%s", dlerror() );
94 0 : return NULL;
95 : }
96 :
97 336 : pSymbol = dlsym( pLibrary, pszSymbolName );
98 :
99 : #if (defined(__APPLE__) && defined(__MACH__))
100 : /* On mach-o systems, C symbols have a leading underscore and depending
101 : * on how dlcompat is configured it may or may not add the leading
102 : * underscore. So if dlsym() fails add an underscore and try again.
103 : */
104 : if( pSymbol == NULL )
105 : {
106 : char withUnder[strlen(pszSymbolName) + 2];
107 : withUnder[0] = '_'; withUnder[1] = 0;
108 : strcat(withUnder, pszSymbolName);
109 : pSymbol = dlsym( pLibrary, withUnder );
110 : }
111 : #endif
112 :
113 336 : if( pSymbol == NULL )
114 : {
115 : CPLError( CE_Failure, CPLE_AppDefined,
116 0 : "%s", dlerror() );
117 0 : return NULL;
118 : }
119 :
120 336 : return( pSymbol );
121 : }
122 :
123 : #endif /* def __unix__ && defined(HAVE_DLFCN_H) */
124 :
125 : /* ==================================================================== */
126 : /* Windows Implementation */
127 : /* ==================================================================== */
128 : #if defined(WIN32) && !defined(WIN32CE)
129 :
130 : #define GOT_GETSYMBOL
131 :
132 : #include <windows.h>
133 :
134 : /************************************************************************/
135 : /* CPLGetSymbol() */
136 : /************************************************************************/
137 :
138 : void *CPLGetSymbol( const char * pszLibrary, const char * pszSymbolName )
139 :
140 : {
141 : void *pLibrary;
142 : void *pSymbol;
143 :
144 : pLibrary = LoadLibrary(pszLibrary);
145 : if( pLibrary == NULL )
146 : {
147 : LPVOID lpMsgBuf = NULL;
148 : int nLastError = GetLastError();
149 :
150 : FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER
151 : | FORMAT_MESSAGE_FROM_SYSTEM
152 : | FORMAT_MESSAGE_IGNORE_INSERTS,
153 : NULL, nLastError,
154 : MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
155 : (LPTSTR) &lpMsgBuf, 0, NULL );
156 :
157 : CPLError( CE_Failure, CPLE_AppDefined,
158 : "Can't load requested DLL: %s\n%d: %s",
159 : pszLibrary, nLastError, (const char *) lpMsgBuf );
160 : return NULL;
161 : }
162 :
163 : pSymbol = (void *) GetProcAddress( (HINSTANCE) pLibrary, pszSymbolName );
164 :
165 : if( pSymbol == NULL )
166 : {
167 : CPLError( CE_Failure, CPLE_AppDefined,
168 : "Can't find requested entry point: %s\n", pszSymbolName );
169 : return NULL;
170 : }
171 :
172 : return( pSymbol );
173 : }
174 :
175 : #endif /* def _WIN32 */
176 :
177 : /* ==================================================================== */
178 : /* Windows CE Implementation */
179 : /* ==================================================================== */
180 : #if defined(WIN32CE)
181 :
182 : #define GOT_GETSYMBOL
183 :
184 : #include "cpl_win32ce_api.h"
185 :
186 : /************************************************************************/
187 : /* CPLGetSymbol() */
188 : /************************************************************************/
189 :
190 : void *CPLGetSymbol( const char * pszLibrary, const char * pszSymbolName )
191 :
192 : {
193 : void *pLibrary;
194 : void *pSymbol;
195 :
196 : pLibrary = CE_LoadLibraryA(pszLibrary);
197 : if( pLibrary == NULL )
198 : {
199 : CPLError( CE_Failure, CPLE_AppDefined,
200 : "Can't load requested DLL: %s", pszLibrary );
201 : return NULL;
202 : }
203 :
204 : pSymbol = (void *) CE_GetProcAddressA( (HINSTANCE) pLibrary, pszSymbolName );
205 :
206 : if( pSymbol == NULL )
207 : {
208 : CPLError( CE_Failure, CPLE_AppDefined,
209 : "Can't find requested entry point: %s\n", pszSymbolName );
210 : return NULL;
211 : }
212 :
213 : return( pSymbol );
214 : }
215 :
216 : #endif /* def WIN32CE */
217 :
218 : /* ==================================================================== */
219 : /* Dummy implementation. */
220 : /* ==================================================================== */
221 :
222 : #ifndef GOT_GETSYMBOL
223 :
224 : /************************************************************************/
225 : /* CPLGetSymbol() */
226 : /* */
227 : /* Dummy implementation. */
228 : /************************************************************************/
229 :
230 : void *CPLGetSymbol(const char *pszLibrary, const char *pszEntryPoint)
231 :
232 : {
233 : CPLDebug( "CPL",
234 : "CPLGetSymbol(%s,%s) called. Failed as this is stub"
235 : " implementation.", pszLibrary, pszEntryPoint );
236 : return NULL;
237 : }
238 : #endif
|