Updating built in Io code to use += instead of x = x + y
[io/quag.git] / libs / basekit / source / DynLib.c
blobac6fb745d872650f636d1ef235309ce7a50bcc3b
1 /*
2 docLicense("BSD revised")
3 docCredits("based on DllHandle.c, contributed by Daniel A. Koepke
4 Reorg, Steve Dekorte, 2003-08-30
5 Window fix, Chuck Adams, 2004-02-06:)
6 */
8 #include "Base.h"
9 #include "DynLib.h"
10 #include "PortableStrlcpy.h"
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
16 #if defined(__WIN32__) || defined(WIN32) || defined(_WIN32) || defined(_MSC_VER)
17 #include <windows.h>
19 #define RTLD_NOW 0 /* don't support link flags */
20 #define RTLD_GLOBAL 0
22 static void *dlopen(const char *path, int mode)
24 void *result;
25 result = (void *)LoadLibraryEx(path, NULL, 0);
26 if (result)
27 SetLastError(ERROR_SUCCESS);
29 return result;
32 static int dlclose(void *handle)
34 return FreeLibrary((HANDLE)handle);
37 static const char *dlerror(void)
39 // XXX this will leak the error string
41 LPSTR buf;
42 DWORD err;
43 err = GetLastError();
44 if (err == ERROR_SUCCESS)
45 return (char*)0;
47 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
48 | FORMAT_MESSAGE_IGNORE_INSERTS
49 | FORMAT_MESSAGE_FROM_SYSTEM,
50 NULL, err,
51 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
52 (LPSTR)&buf, 0, NULL);
53 return buf;
56 static void *dlsym(void *handle, const char *symbol)
58 return (void*)GetProcAddress((HANDLE)handle, symbol);
62 #else
63 #include <dlfcn.h>
64 #endif
66 DynLib *DynLib_new(void)
68 DynLib *self = (DynLib *)io_calloc(1, sizeof(DynLib));
69 DynLib_setPath_(self, "");
70 return self;
73 void DynLib_free(DynLib *self)
75 //DynLib_close(self);
76 if (self->path) io_free(self->path);
77 if (self->initFuncName) io_free(self->initFuncName);
78 if (self->freeFuncName) io_free(self->freeFuncName);
79 if (self->error) io_free(self->error);
80 io_free(self);
83 void DynLib_setPath_(DynLib *self, const char *path)
85 size_t len = strlen(path);
86 char *ptr = (char*)io_realloc(self->path, len + 1);
87 PortableStrlcpy(ptr, path, len + 1);
88 self->path = ptr;
91 char *DynLib_path(DynLib *self)
93 return self->path;
96 void DynLib_setInitFuncName_(DynLib *self, const char *name)
98 size_t len = strlen(name);
99 char* ptr = (char*)io_realloc(self->initFuncName, len + 1);
100 PortableStrlcpy(ptr, name, len + 1);
101 self->initFuncName = ptr;
104 char *DynLib_initFuncName(DynLib *self)
106 return self->initFuncName;
109 void DynLib_setInitArg_(DynLib *self, void *arg)
111 self->initArg = arg;
114 void DynLib_setFreeFuncName_(DynLib *self, const char *name)
116 size_t len = strlen(name);
117 char* ptr = (char*)io_realloc(self->freeFuncName, len + 1);
118 PortableStrlcpy(ptr, name, len + 1);
119 self->freeFuncName = ptr;
122 char *DynLib_freeFuncName(DynLib *self)
124 return self->freeFuncName;
127 void DynLib_setFreeArg_(DynLib *self, void *arg)
129 self->freeArg = arg;
132 void DynLib_setError_(DynLib *self,const char *error)
134 if (error)
136 self->error = strcpy((char *)io_realloc(self->error, strlen(error)+1), error);
138 else
140 if (self->error) io_free(self->error);
141 self->error = NULL;
145 char *DynLib_error(DynLib *self)
147 return self->error;
150 void DynLib_updateError(DynLib *self)
152 DynLib_setError_(self, dlerror());
155 unsigned char DynLib_hasError(DynLib *self)
157 return self->error != NULL;
160 void DynLib_open(DynLib *self)
162 self->handle = dlopen(self->path, RTLD_NOW | RTLD_GLOBAL); /* RTLD_LAZY); */
163 //self->handle = dlopen(self->path, RTLD_NOW | RTLD_LAZY);
164 DynLib_updateError(self);
166 if (DynLib_hasError(self))
168 return;
171 if (self->initFuncName)
173 void *f = DynLib_pointerForSymbolName_(self, self->initFuncName);
175 if (!f)
177 DynLib_setError_(self, "init function not found");
178 return;
181 if (self->initArg)
183 //printf("DynLib: opening with 1 arg %p\n", self->initArg);
184 (*(DynLibOneArgFunction *)f)(self->initArg);
186 else
188 (*(DynLibNoArgFunction *)f)();
193 unsigned char DynLib_isOpen(DynLib *self)
195 return self->handle != NULL;
198 void DynLib_close(DynLib *self)
200 if (self->freeFuncName)
202 void *f = DynLib_pointerForSymbolName_(self, self->freeFuncName);
204 if (!f)
206 DynLib_setError_(self, "io_free function not found");
207 return;
210 if (self->freeArg)
212 (*(DynLibOneArgFunction *)f)(self->freeArg);
214 else
216 (*(DynLibNoArgFunction *)f)();
220 if (self->handle)
222 dlclose(self->handle);
225 self->handle = NULL;
228 void *DynLib_pointerForSymbolName_(DynLib *self, const char *symbolName)
230 DynLib_setError_(self, dlerror());
231 return dlsym(self->handle, symbolName);