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