comparison src/SDL_loadso.c @ 294:d2d48e10f370

Added a new header file: SDL_loadso.h It contains the following functions: SDL_LoadObject(), SDL_LoadFunction(), SDL_UnloadObject() The UNIX esd and arts audio code use these to dynamically load their respective audio libraries.
author Sam Lantinga <slouken@libsdl.org>
date Wed, 06 Mar 2002 05:20:11 +0000
parents
children fab1ddc4d7bf
comparison
equal deleted inserted replaced
293:585a7e1285ae 294:d2d48e10f370
1 /*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the Free
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 Sam Lantinga
20 slouken@libsdl.org
21 */
22
23 #ifdef SAVE_RCSID
24 static char rcsid =
25 "@(#) $Id$";
26 #endif
27
28 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
29 /* System dependent library loading routines */
30
31 #include <stdio.h>
32 #if defined(USE_DLOPEN)
33 # include <dlfcn.h>
34 #elif defined(WIN32)
35 # include <windows.h>
36 #elif defined(__BEOS__)
37 # include <be/kernel/image.h>
38 #elif defined(macintosh)
39 # include <string.h>
40 # include <Strings.h>
41 # include <CodeFragments.h>
42 # include <Errors.h>
43 #else
44 /*#error Unsupported dynamic link environment*/
45 #endif /* system type */
46
47 #include "SDL_error.h"
48 #include "SDL_loadso.h"
49
50 void *SDL_LoadObject(const char *sofile)
51 {
52 void *handle = NULL;
53 const char *loaderror = "SDL_LoadObject() not implemented";
54 #if defined(USE_DLOPEN)
55 /* * */
56 handle = dlopen(sofile, RTLD_NOW);
57 loaderror = (char *)dlerror();
58 #elif defined(WIN32)
59 /* * */
60 char errbuf[512];
61
62 handle = (void *)LoadLibrary(sofile);
63
64 /* Generate an error message if all loads failed */
65 if ( handle == NULL ) {
66 FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS |
67 FORMAT_MESSAGE_FROM_SYSTEM),
68 NULL, GetLastError(),
69 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
70 errbuf, SDL_TABLESIZE(errbuf), NULL);
71 loaderror = errbuf;
72 }
73 #elif defined(__BEOS__)
74 /* * */
75 image_id library_id;
76
77 library_id = load_add_on(sofile);
78 if ( library_id == B_ERROR ) {
79 loaderror = "BeOS error";
80 } else {
81 handle = (void *)(library_id);
82 }
83 #elif defined(macintosh)
84 /* * */
85 CFragConnectionID library_id;
86 Ptr mainAddr;
87 Str255 errName;
88 OSErr error;
89 char psofile[512];
90
91 strncpy(psofile, sofile, SDL_TABLESIZE(psofile));
92 psofile[SDL_TABLESIZE(psofile)-1] = '\0';
93 error = GetSharedLibrary(C2PStr(psofile), kCompiledCFragArch,
94 kLoadCFrag, &library_id, &mainAddr, errName);
95 switch (error) {
96 case noErr:
97 break;
98 case cfragNoLibraryErr:
99 loaderror = "Library not found";
100 break;
101 case cfragUnresolvedErr:
102 loaderror = "Unabled to resolve symbols";
103 break;
104 case cfragNoPrivateMemErr:
105 case cfragNoClientMemErr:
106 loaderror = "Out of memory";
107 break;
108 default:
109 loaderror = "Unknown Code Fragment Manager error";
110 break;
111 }
112 if ( loaderror == NULL ) {
113 handle = (void *)(library_id);
114 }
115 #endif /* system type */
116
117 if ( handle == NULL ) {
118 SDL_SetError("Failed loading %s: %s", sofile, loaderror);
119 }
120 return(handle);
121 }
122
123 void *SDL_LoadFunction(void *handle, const char *name)
124 {
125 void *symbol = NULL;
126 const char *loaderror = "SDL_LoadFunction not implemented";
127 #if defined(USE_DLOPEN)
128 /* * */
129 symbol = dlsym(handle, name);
130 if ( symbol == NULL ) {
131 loaderror = (char *)dlerror();
132 }
133 #elif defined(WIN32)
134 /* * */
135 char errbuf[512];
136
137 symbol = (void *)GetProcAddress((HMODULE)handle, name);
138 if ( symbol == NULL ) {
139 FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS |
140 FORMAT_MESSAGE_FROM_SYSTEM),
141 NULL, GetLastError(),
142 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
143 errbuf, SDL_TABLESIZE(errbuf), NULL);
144 loaderror = errbuf;
145 }
146 #elif defined(__BEOS__)
147 /* * */
148 image_id library_id = (image_id)handle;
149 if ( get_image_symbol(library_id,
150 name, B_SYMBOL_TYPE_TEXT, &symbol) != B_NO_ERROR ) {
151 loaderror = "Symbol not found";
152 }
153 #elif defined(macintosh)
154 /* * */
155 CFragSymbolClass class;
156 CFragConnectionID library_id = (CFragConnectionID)handle;
157 char pname[512];
158
159 strncpy(pname, name, SDL_TABLESIZE(pname));
160 pname[SDL_TABLESIZE(pname)-1] = '\0';
161 if ( FindSymbol(library_id, C2PStr(pname),
162 (char **)&symbol, &class) != noErr ) {
163 loaderror = "Symbol not found";
164 }
165 #endif /* system type */
166
167 if ( symbol == NULL ) {
168 SDL_SetError("Failed loading %s: %s", name, loaderror);
169 }
170 return(symbol);
171 }
172
173 void SDL_UnloadObject(void *handle)
174 {
175 if ( handle == NULL ) {
176 return;
177 }
178 #if defined(USE_DLOPEN)
179 /* * */
180 dlclose(handle);
181 #elif defined(WIN32)
182 /* * */
183 FreeLibrary((HMODULE)handle);
184 #elif defined(__BEOS__)
185 /* * */
186 image_id library_id = (image_id)handle;
187 unload_add_on(library_id);
188 #elif defined(macintosh)
189 /* * */
190 CFragConnectionID library_id = (CFragConnectionID)handle;
191 CloseConnection(library_id);
192 #endif /* system type */
193 }