]> git.imager.perl.org - imager.git/blob - dynaload.c
merge circle outline branch
[imager.git] / dynaload.c
1 #if defined(OS_hpux)
2 #include <dl.h>
3 typedef shl_t minthandle_t;
4 #elif defined(WIN32)
5 #define WIN32_LEAN_AND_MEAN
6 #include <windows.h>
7 typedef HMODULE minthandle_t;
8 #undef WIN32_LEAN_AND_MEAN
9 #else 
10 #include <dlfcn.h>
11 typedef void *minthandle_t; 
12 #endif 
13
14 #include "plug.h"
15
16 struct DSO_handle_tag {
17   minthandle_t handle;
18   char *filename;
19   func_ptr *function_list;
20 };
21
22 #include "imager.h"
23 #include "dynaload.h"
24 /* #include "XSUB.h"  so we can compile on threaded perls */
25 #include "imageri.h"
26
27 static symbol_table_t symbol_table=
28   {
29     i_has_format,
30     ICL_set_internal,
31     ICL_info,
32     i_img_new,
33     i_img_empty,
34     i_img_empty_ch,
35     i_img_exorcise,
36     i_img_info,
37     i_img_setmask,
38     i_img_getmask,
39     i_box,
40     i_line,
41     i_arc,
42     i_copyto,
43     i_copyto_trans,
44     i_rubthru
45   };
46
47
48 /*
49   Dynamic loading works like this:
50   dynaload opens the shared object and
51   loads all the functions into an array of functions
52   it returns a string from the dynamic function that
53   can be supplied to the parser for evaling.
54 */
55
56 void
57 DSO_call(DSO_handle *handle,int func_index,HV* hv) {
58   mm_log((1,"DSO_call(handle 0x%X, func_index %d, hv 0x%X)\n",handle,func_index,hv));
59   (handle->function_list[func_index].iptr)((void*)hv);
60 }
61
62 func_ptr *
63 DSO_funclist(DSO_handle *handle) {
64   return handle->function_list;
65 }
66
67
68 #if defined( OS_hpux )
69
70 void*
71 DSO_open(char* file,char** evalstring) {
72   shl_t tt_handle;
73   void *d_handle,**plugin_symtab,**plugin_utiltab;
74   int  rc,*iptr, (*fptr)(int);
75   func_ptr *function_list;
76   DSO_handle *dso_handle;
77   void (*f)(void *s,void *u); /* these will just have to be void for now */
78   int i;
79
80   *evalstring=NULL;
81
82   mm_log( (1,"DSO_open(file '%s' (0x%08X), evalstring 0x%08X)\n",file,file,evalstring) );
83
84   if ( (tt_handle = shl_load(file, BIND_DEFERRED,0L)) == NULL) return NULL; 
85   if ( (shl_findsym(&tt_handle, I_EVALSTR,TYPE_UNDEFINED,(void*)evalstring))) return NULL;
86
87   /*
88   if ( (shl_findsym(&tt_handle, "symbol_table",TYPE_UNDEFINED,(void*)&plugin_symtab))) return NULL;
89   if ( (shl_findsym(&tt_handle, "util_table",TYPE_UNDEFINED,&plugin_utiltab))) return NULL;
90   (*plugin_symtab)=&symbol_table;
91   (*plugin_utiltab)=&i_UTIL_table;
92   */
93
94   if ( (shl_findsym(&tt_handle, I_INSTALL_TABLES ,TYPE_UNDEFINED, &f ))) return NULL; 
95  
96   mm_log( (1,"Calling install_tables\n") );
97   f(&symbol_table,&i_UTIL_table);
98   mm_log( (1,"Call ok.\n") ); 
99  
100   if ( (shl_findsym(&tt_handle, I_FUNCTION_LIST ,TYPE_UNDEFINED,(func_ptr*)&function_list))) return NULL; 
101   if ( (dso_handle=(DSO_handle*)malloc(sizeof(DSO_handle))) == NULL) /* checked 17jul05 tonyc */
102     return NULL;
103
104   dso_handle->handle=tt_handle; /* needed to close again */
105   dso_handle->function_list=function_list;
106   if ( (dso_handle->filename=(char*)malloc(strlen(file)+1)) == NULL) { /* checked 17jul05 tonyc */
107     free(dso_handle); return NULL;
108   }
109   strcpy(dso_handle->filename,file);
110
111   mm_log((1,"DSO_open <- (0x%X)\n",dso_handle));
112   return (void*)dso_handle;
113 }
114
115 undef_int
116 DSO_close(void *ptr) {
117   DSO_handle *handle=(DSO_handle*) ptr;
118   mm_log((1,"DSO_close(ptr 0x%X)\n",ptr));
119   return !shl_unload((handle->handle));
120 }
121
122 #elif defined(WIN32)
123
124 void *
125 DSO_open(char *file, char **evalstring) {
126   HMODULE d_handle;
127   func_ptr *function_list;
128   DSO_handle *dso_handle;
129   
130   void (*f)(void *s,void *u); /* these will just have to be void for now */
131
132   mm_log( (1,"DSO_open(file '%s' (0x%08X), evalstring 0x%08X)\n",file,file,evalstring) );
133
134   *evalstring = NULL;
135   if ((d_handle = LoadLibrary(file)) == NULL) {
136     mm_log((1, "DSO_open: LoadLibrary(%s) failed: %lu\n", file, GetLastError()));
137     return NULL;
138   }
139   if ( (*evalstring = (char *)GetProcAddress(d_handle, I_EVALSTR)) == NULL) {
140     mm_log((1,"DSO_open: GetProcAddress didn't fine '%s': %lu\n", I_EVALSTR, GetLastError()));
141     FreeLibrary(d_handle);
142     return NULL;
143   }
144   if ((f = (void (*)(void *, void*))GetProcAddress(d_handle, I_INSTALL_TABLES)) == NULL) {
145     mm_log((1, "DSO_open: GetProcAddress didn't find '%s': %lu\n", I_INSTALL_TABLES, GetLastError()));
146     FreeLibrary(d_handle);
147     return NULL;
148   }
149   mm_log((1, "Calling install tables\n"));
150   f(&symbol_table, &i_UTIL_table);
151   mm_log((1, "Call ok\n"));
152   
153   if ( (function_list = (func_ptr *)GetProcAddress(d_handle, I_FUNCTION_LIST)) == NULL) {
154     mm_log((1, "DSO_open: GetProcAddress didn't find '%s': %lu\n", I_FUNCTION_LIST, GetLastError()));
155     FreeLibrary(d_handle);
156     return NULL;
157   }
158   if ( (dso_handle = (DSO_handle*)malloc(sizeof(DSO_handle))) == NULL) { /* checked 17jul05 tonyc */
159     mm_log( (1, "DSO_Open: out of memory\n") );
160     FreeLibrary(d_handle);
161     return NULL;
162   }
163   dso_handle->handle=d_handle; /* needed to close again */
164   dso_handle->function_list=function_list;
165   if ( (dso_handle->filename=(char*)malloc(strlen(file)+1)) == NULL) { /* checked 17jul05 tonyc */
166     free(dso_handle);
167     FreeLibrary(d_handle); 
168     return NULL; 
169   }
170   strcpy(dso_handle->filename,file);
171
172   mm_log( (1,"DSO_open <- 0x%X\n",dso_handle) );
173   return (void*)dso_handle;
174
175 }
176
177 undef_int
178 DSO_close(void *ptr) {
179   DSO_handle *handle = (DSO_handle *)ptr;
180   BOOL result = FreeLibrary(handle->handle);
181   free(handle->filename);
182   free(handle);
183
184   return result;
185 }
186
187 #else
188
189 /* OS/2 has no dlclose; Perl doesn't provide one. */
190 #ifdef __EMX__ /* OS/2 */
191 int
192 dlclose(minthandle_t h) {
193   return DosFreeModule(h) ? -1 : 0;
194 }
195 #endif /* __EMX__ */
196
197 void*
198 DSO_open(char* file,char** evalstring) {
199   void *d_handle;
200   func_ptr *function_list;
201   DSO_handle *dso_handle;
202
203   void (*f)(void *s,void *u); /* these will just have to be void for now */
204   
205   *evalstring=NULL;
206
207   mm_log( (1,"DSO_open(file '%s' (0x%08X), evalstring 0x%08X)\n",file,file,evalstring) );
208
209   if ( (d_handle = dlopen(file, RTLD_LAZY)) == NULL) {
210     mm_log( (1,"DSO_open: dlopen failed: %s.\n",dlerror()) );
211     return NULL;
212   }
213
214   if ( (*evalstring = (char *)dlsym(d_handle, I_EVALSTR)) == NULL) {
215     mm_log( (1,"DSO_open: dlsym didn't find '%s': %s.\n",I_EVALSTR,dlerror()) );
216     return NULL;
217   }
218
219   /*
220
221     I'll just leave this thing in here for now if I need it real soon
222
223    mm_log( (1,"DSO_open: going to dlsym '%s'\n", I_SYMBOL_TABLE ));
224    if ( (plugin_symtab = dlsym(d_handle, I_SYMBOL_TABLE)) == NULL) {
225      mm_log( (1,"DSO_open: dlsym didn't find '%s': %s.\n",I_SYMBOL_TABLE,dlerror()) );
226      return NULL;
227    }
228   
229    mm_log( (1,"DSO_open: going to dlsym '%s'\n", I_UTIL_TABLE ));
230     if ( (plugin_utiltab = dlsym(d_handle, I_UTIL_TABLE)) == NULL) {
231      mm_log( (1,"DSO_open: dlsym didn't find '%s': %s.\n",I_UTIL_TABLE,dlerror()) );
232      return NULL;
233    }
234
235   */
236
237   f = (void(*)(void *s,void *u))dlsym(d_handle, I_INSTALL_TABLES);
238   mm_log( (1,"DSO_open: going to dlsym '%s'\n", I_INSTALL_TABLES ));
239   if ( (f = (void(*)(void *s,void *u))dlsym(d_handle, I_INSTALL_TABLES)) == NULL) {
240     mm_log( (1,"DSO_open: dlsym didn't find '%s': %s.\n",I_INSTALL_TABLES,dlerror()) );
241     return NULL;
242   }
243
244   mm_log( (1,"Calling install_tables\n") );
245   f(&symbol_table,&i_UTIL_table);
246   mm_log( (1,"Call ok.\n") );
247
248   /* (*plugin_symtab)=&symbol_table;
249      (*plugin_utiltab)=&i_UTIL_table; */
250   
251   mm_log( (1,"DSO_open: going to dlsym '%s'\n", I_FUNCTION_LIST ));
252   if ( (function_list=(func_ptr *)dlsym(d_handle, I_FUNCTION_LIST)) == NULL) {
253     mm_log( (1,"DSO_open: dlsym didn't find '%s': %s.\n",I_FUNCTION_LIST,dlerror()) );
254     return NULL;
255   }
256   
257   if ( (dso_handle=(DSO_handle*)malloc(sizeof(DSO_handle))) == NULL) /* checked 17jul05 tonyc */
258     return NULL;
259   
260   dso_handle->handle=d_handle; /* needed to close again */
261   dso_handle->function_list=function_list;
262   if ( (dso_handle->filename=(char*)malloc(strlen(file)+1)) == NULL) { /* checked 17jul05 tonyc */
263     free(dso_handle); 
264     return NULL;
265   }
266   strcpy(dso_handle->filename,file);
267
268   mm_log( (1,"DSO_open <- 0x%X\n",dso_handle) );
269   return (void*)dso_handle;
270 }
271
272 undef_int
273 DSO_close(void *ptr) {
274   DSO_handle *handle;
275   mm_log((1,"DSO_close(ptr 0x%X)\n",ptr));
276   handle=(DSO_handle*) ptr;
277   return !dlclose(handle->handle);
278 }
279
280 #endif
281