1 /* nl-import.c --- shared library interface for newLISP
3 Copyright (C) 2008 Lutz Mueller
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program 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
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #define _stdcall __stdcall
31 #include "osx-dlfcn.h"
37 UINT
cdeclFunction(UINT fAddress
, UINT
* args
, int count
);
39 extern int evalCatchFlag
;
44 UINT
stdcallFunction(UINT fAddress
, UINT
* args
, int count
);
47 CELL
* p_importLib(CELL
* params
)
51 char * options
= NULL
;
57 params
= getString(params
, &libName
);
58 params
= getString(params
, &funcName
);
60 getString(params
, &options
);
62 /* hLibrary = NULL; */
64 if( (UINT
)(hLibrary
= LoadLibrary(libName
)) < 32)
65 return(errorProcExt2(ERR_IMPORT_LIB_NOT_FOUND
, stuffString(libName
)));
67 if(options
!= NULL
&& strcmp(options
, "cdecl") == 0)
68 pCell
= getCell(CELL_IMPORT_CDECL
);
70 pCell
= getCell(CELL_IMPORT_DLL
);
72 symbol
= translateCreateSymbol(funcName
, pCell
->type
, currentContext
, TRUE
);
73 if(isProtected(symbol
->flags
))
74 return(errorProcExt2(ERR_SYMBOL_PROTECTED
, stuffSymbol(symbol
)));
76 deleteList((CELL
*)symbol
->contents
);
77 symbol
->contents
= (UINT
)pCell
;
78 pCell
->contents
= (UINT
)GetProcAddress(hLibrary
, (LPCSTR
)funcName
);
79 pCell
->aux
= (UINT
)symbol
->name
;
81 /* put name of imported DLL into DLLs space for loadStartup() */
82 initProc
= GetProcAddress(hLibrary
, (LPCSTR
)"dllName");
83 if(initProc
!= 0) (*initProc
)(libName
);
85 if(pCell
->contents
== 0)
86 return(errorProcExt2(ERR_IMPORT_FUNC_NOT_FOUND
, stuffString(funcName
)));
88 return(copyCell(pCell
));
91 #else /* UNIX and compatible operating systems */
93 CELL
* p_importLib(CELL
* params
)
102 params
= getString(params
, &libName
);
103 getString(params
, &funcName
);
107 if((hLibrary
= dlopen(libName
, RTLD_LAZY
)) == 0)
109 if((hLibrary
= dlopen(libName
, RTLD_GLOBAL
|RTLD_LAZY
)) == 0)
111 return(errorProcExt2(ERR_IMPORT_LIB_NOT_FOUND
, stuffString((char *)dlerror())));
113 pCell
= getCell(CELL_IMPORT_CDECL
);
114 symbol
= translateCreateSymbol(funcName
, CELL_IMPORT_CDECL
, currentContext
, TRUE
);
115 if(isProtected(symbol
->flags
))
116 return(errorProcExt2(ERR_SYMBOL_PROTECTED
, stuffSymbol(symbol
)));
118 deleteList((CELL
*)symbol
->contents
);
119 symbol
->contents
= (UINT
)pCell
;
121 pCell
->contents
= (UINT
)dlsym(hLibrary
, funcName
);
123 if((error
= (char *)dlerror()) != NULL
)
124 return(errorProcExt2(ERR_IMPORT_FUNC_NOT_FOUND
, stuffString(error
)));
126 pCell
->aux
= (UINT
)symbol
->name
;
128 return(copyCell(pCell
));
134 CELL
* executeLibfunction(CELL
* pCell
, CELL
* params
)
141 while(params
->type
!= CELL_NIL
&& count
< 14)
143 arg
= evaluateExpression(params
);
149 args
[count
++] = arg
->contents
;
153 args
[count
++] = *(INT64
*)&arg
->aux
;
158 args
[count
++] = arg
->aux
;
160 args
[count
++] = arg
->contents
;
164 args
[count
++] = (UINT
)arg
;
167 params
= (CELL
*)params
->next
;
171 if(pCell
->type
== CELL_IMPORT_DLL
)
172 return(stuffInteger(stdcallFunction(pCell
->contents
, args
, count
)));
175 return(stuffInteger(cdeclFunction(pCell
->contents
, args
, count
)));
179 UINT
cdeclFunction(UINT fAddress
, UINT
* args
, int count
)
183 function
= (UINT (*)())fAddress
;
188 return (*function
)();
191 return (*function
)(args
[0]);
194 return (*function
)(args
[0], args
[1]);
197 return (*function
)(args
[0], args
[1], args
[2]);
200 return (*function
)(args
[0], args
[1], args
[2], args
[3]);
203 return (*function
)(args
[0], args
[1], args
[2], args
[3],
206 return (*function
)(args
[0], args
[1], args
[2], args
[3],
209 return (*function
)(args
[0], args
[1], args
[2], args
[3],
210 args
[4], args
[5], args
[6]);
212 return (*function
)(args
[0], args
[1], args
[2], args
[3],
213 args
[4], args
[5], args
[6], args
[7]);
216 return (*function
)(args
[0], args
[1], args
[2], args
[3],
217 args
[4], args
[5], args
[6], args
[7], args
[8]);
220 return (*function
)(args
[0], args
[1], args
[2], args
[3],
221 args
[4], args
[5], args
[6], args
[7], args
[8], args
[9]);
223 return (*function
)(args
[0], args
[1], args
[2], args
[3],
224 args
[4], args
[5], args
[6], args
[7],
225 args
[8], args
[9], args
[10]);
227 return (*function
)(args
[0], args
[1], args
[2], args
[3],
228 args
[4], args
[5], args
[6], args
[7],
229 args
[8], args
[9], args
[10], args
[11]);
232 return (*function
)(args
[0], args
[1], args
[2], args
[3],
233 args
[4], args
[5], args
[6], args
[7],
234 args
[8], args
[9], args
[10], args
[11],
237 return (*function
)(args
[0], args
[1], args
[2], args
[3],
238 args
[4], args
[5], args
[6], args
[7],
239 args
[8], args
[9], args
[10], args
[11],
250 UINT
stdcallFunction(UINT fAddress
, UINT
* args
, int count
)
252 UINT
_stdcall (*function
)();
254 function
= (UINT
_stdcall (*)())fAddress
;
259 return (*function
)();
262 return (*function
)(args
[0]);
265 return (*function
)(args
[0], args
[1]);
268 return (*function
)(args
[0], args
[1], args
[2]);
271 return (*function
)(args
[0], args
[1], args
[2], args
[3]);
274 return (*function
)(args
[0], args
[1], args
[2], args
[3],
277 return (*function
)(args
[0], args
[1], args
[2], args
[3],
280 return (*function
)(args
[0], args
[1], args
[2], args
[3],
281 args
[4], args
[5], args
[6]);
283 return (*function
)(args
[0], args
[1], args
[2], args
[3],
284 args
[4], args
[5], args
[6], args
[7]);
287 return (*function
)(args
[0], args
[1], args
[2], args
[3],
288 args
[4], args
[5], args
[6], args
[7], args
[8]);
291 return (*function
)(args
[0], args
[1], args
[2], args
[3],
292 args
[4], args
[5], args
[6], args
[7], args
[8], args
[9]);
294 return (*function
)(args
[0], args
[1], args
[2], args
[3],
295 args
[4], args
[5], args
[6], args
[7],
296 args
[8], args
[9], args
[10]);
298 return (*function
)(args
[0], args
[1], args
[2], args
[3],
299 args
[4], args
[5], args
[6], args
[7],
300 args
[8], args
[9], args
[10], args
[11]);
303 return (*function
)(args
[0], args
[1], args
[2], args
[3],
304 args
[4], args
[5], args
[6], args
[7],
305 args
[8], args
[9], args
[10], args
[11],
308 return (*function
)(args
[0], args
[1], args
[2], args
[3],
309 args
[4], args
[5], args
[6], args
[7],
310 args
[8], args
[9], args
[10], args
[11],
321 /* used when passing 32bit floats to library routines */
322 CELL
* p_flt(CELL
* params
)
328 getFloat(params
, &dfloatV
);
331 memcpy(&number
, &floatV
, 4);
333 return(stuffInteger(number
));
337 /* 8 callback functions for up to 4 parameters */
339 long template(long n
, long p1
, long p2
, long p3
, long p4
);
341 long callback0(long p1
, long p2
, long p3
, long p4
) {return template(0, p1
, p2
, p3
, p4
);}
342 long callback1(long p1
, long p2
, long p3
, long p4
) {return template(1, p1
, p2
, p3
, p4
);}
343 long callback2(long p1
, long p2
, long p3
, long p4
) {return template(2, p1
, p2
, p3
, p4
);}
344 long callback3(long p1
, long p2
, long p3
, long p4
) {return template(3, p1
, p2
, p3
, p4
);}
345 long callback4(long p1
, long p2
, long p3
, long p4
) {return template(4, p1
, p2
, p3
, p4
);}
346 long callback5(long p1
, long p2
, long p3
, long p4
) {return template(5, p1
, p2
, p3
, p4
);}
347 long callback6(long p1
, long p2
, long p3
, long p4
) {return template(6, p1
, p2
, p3
, p4
);}
348 long callback7(long p1
, long p2
, long p3
, long p4
) {return template(7, p1
, p2
, p3
, p4
);}
355 LIBCALLBACK callback
[] = {
356 { NULL
, (UINT
)callback0
},
357 { NULL
, (UINT
)callback1
},
358 { NULL
, (UINT
)callback2
},
359 { NULL
, (UINT
)callback3
},
360 { NULL
, (UINT
)callback4
},
361 { NULL
, (UINT
)callback5
},
362 { NULL
, (UINT
)callback6
},
363 { NULL
, (UINT
)callback7
},
367 long template(long n
, long p1
, long p2
, long p3
, long p4
)
371 jmp_buf errorJumpSave
;
373 memcpy(errorJumpSave
, errorJump
, sizeof(errorJump
));
374 if(setjmp(errorJump
))
379 goto FINISH_CALLBACK
;
382 args
= stuffIntegerList(4, p1
, p2
, p3
, p4
);
383 result
= executeSymbol(callback
[n
].sym
, (CELL
*)args
->contents
);
384 args
->contents
= (UINT
)nilCell
;
388 memcpy(errorJump
, errorJumpSave
, sizeof(errorJump
));
392 CELL
* p_callback(CELL
* params
)
397 params
= getInteger(params
, &n
);
399 getSymbol(params
, &sPtr
);
401 callback
[n
].sym
= sPtr
;
403 return(stuffInteger(callback
[n
].func
));