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:)
10 #include "PortableStrlcpy.h"
16 #if defined(__WIN32__) || defined(WIN32) || defined(_WIN32) || defined(_MSC_VER)
19 #define RTLD_NOW 0 /* don't support link flags */
22 static void *dlopen(const char *path
, int mode
)
25 result
= (void *)LoadLibraryEx(path
, NULL
, 0);
27 SetLastError(ERROR_SUCCESS
);
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
44 if (err
== ERROR_SUCCESS
)
47 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
48 | FORMAT_MESSAGE_IGNORE_INSERTS
49 | FORMAT_MESSAGE_FROM_SYSTEM
,
51 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
),
52 (LPSTR
)&buf
, 0, NULL
);
56 static void *dlsym(void *handle
, const char *symbol
)
58 return (void*)GetProcAddress((HANDLE
)handle
, symbol
);
66 DynLib
*DynLib_new(void)
68 DynLib
*self
= (DynLib
*)io_calloc(1, sizeof(DynLib
));
69 DynLib_setPath_(self
, "");
73 void DynLib_free(DynLib
*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
);
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);
91 char *DynLib_path(DynLib
*self
)
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
)
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
)
132 void DynLib_setError_(DynLib
*self
,const char *error
)
136 self
->error
= strcpy((char *)io_realloc(self
->error
, strlen(error
)+1), error
);
140 if (self
->error
) io_free(self
->error
);
145 char *DynLib_error(DynLib
*self
)
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
))
171 if (self
->initFuncName
)
173 void *f
= DynLib_pointerForSymbolName_(self
, self
->initFuncName
);
177 DynLib_setError_(self
, "init function not found");
183 //printf("DynLib: opening with 1 arg %p\n", self->initArg);
184 (*(DynLibOneArgFunction
*)f
)(self
->initArg
);
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
);
206 DynLib_setError_(self
, "io_free function not found");
212 (*(DynLibOneArgFunction
*)f
)(self
->freeArg
);
216 (*(DynLibNoArgFunction
*)f
)();
222 dlclose(self
->handle
);
228 void *DynLib_pointerForSymbolName_(DynLib
*self
, const char *symbolName
)
230 DynLib_setError_(self
, dlerror());
231 return dlsym(self
->handle
, symbolName
);