*** empty log message ***
[chuck-blob.git] / exile / v1 / src / chuck_dl.h
blob3a029efaf3b4dc475b9e396c21de367c66b497e3
1 /*----------------------------------------------------------------------------
2 ChucK Concurrent, On-the-fly Audio Programming Language
3 Compiler and Virtual Machine
5 Copyright (c) 2004 Ge Wang and Perry R. Cook. All rights reserved.
6 http://chuck.cs.princeton.edu/
7 http://soundlab.cs.princeton.edu/
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22 U.S.A.
23 -----------------------------------------------------------------------------*/
25 //-----------------------------------------------------------------------------
26 // name: chuck_dl.h
27 // desc: chuck dynamic linking header
29 // authors: Ge Wang (gewang@cs.princeton.edu)
30 // Perry R. Cook (prc@cs.princeton.edu)
31 // mac os code based on apple's open source
33 // date: spring 2004
34 //-----------------------------------------------------------------------------
35 #ifndef __CHUCK_DL_H__
36 #define __CHUCK_DL_H__
38 #include "chuck_def.h"
39 #include "chuck_oo.h"
40 #include "chuck_ugen.h"
41 #include <stdlib.h>
42 #include <memory.h>
43 #include <string>
44 #include <vector>
45 #include <map>
48 // chuck dll export linkage and calling convention
50 #if defined (__PLATFORM_WIN32__)
51 #define CK_DLL_LINKAGE extern "C" __declspec( dllexport )
52 #else
53 #define CK_DLL_LINKAGE extern "C"
54 #endif
56 #if defined(__WINDOWS_DS__)
57 #define CK_DLL_CALL _cdecl
58 #else
59 #define CK_DLL_CALL
60 #endif
62 // macro for defining ChucK DLL export functions
63 // example: CK_DLL_EXPORT(int) foo() { return 1; }
64 #define CK_DLL_EXPORT(type) CK_DLL_LINKAGE type CK_DLL_CALL
65 // macro for defining ChucK DLL export query-functions
66 // example: CK_DLL_QUERY
67 #define CK_DLL_QUERY CK_DLL_EXPORT(t_CKBOOL) ck_query( Chuck_DL_Query * QUERY )
68 // macro for defining ChucK DLL export functions
69 // example: CK_DLL_FUNC(foo)
70 #define CK_DLL_FUNC(name) CK_DLL_EXPORT(void) name( void * ARGS, Chuck_DL_Return * RETURN )
72 // macros for DLL exports
73 // example: DLL_QUERY query( Chuck_DL_Query * QUERY )
74 // example: DLL_FUNC foo( void * ARGS, Chuck_DL_Return * RETURN )
75 #define DLL_QUERY CK_DLL_EXPORT(t_CKBOOL)
76 #define DLL_FUNC CK_DLL_EXPORT(void)
78 // macros for unit generator export functions
79 // example: UGEN_CTOR foo_ctor( t_CKTIME now )
80 // example: UGEN_DTOR foo_dtor( t_CKTIME now, void * data )
81 // example: UGEN_TICK foo_tick( t_CKTIME now, void * data, SAMPLE in, SAMPLE * out )
82 // example: UGEN_CTRL foo_ctrl_a( t_CKTIME now, void * data, void * value )
83 // example: UGEN_CGET foo_cget_a( t_CKTIME now, void * data, void * out )
84 // example: UGEN_PMSG foo_pmsg( t_CKTIME now, void * data, const char * msg, void * value );
85 #define UGEN_CTOR CK_DLL_EXPORT(void *)
86 #define UGEN_DTOR CK_DLL_EXPORT(void)
87 #define UGEN_TICK CK_DLL_EXPORT(t_CKBOOL)
88 #define UGEN_CTRL CK_DLL_EXPORT(void)
89 #define UGEN_CGET CK_DLL_EXPORT(void)
90 #define UGEN_PMSG CK_DLL_EXPORT(t_CKBOOL)
93 // forward reference
94 struct Chuck_DL_Query;
95 struct Chuck_DL_Proto;
96 union Chuck_DL_Return;
98 // chuck DLL interface
99 #define CK_QUERY_FUNC "ck_query"
100 typedef t_CKBOOL (CK_DLL_CALL * f_ck_query)( Chuck_DL_Query * QUERY );
101 typedef void ( CK_DLL_CALL * f_ck_func)( void * ARGS, Chuck_DL_Return * RETURN );
102 typedef void ( CK_DLL_CALL * f_ck_attach)( t_CKUINT type, void * data );
103 typedef void ( CK_DLL_CALL * f_ck_detach)( t_CKUINT type, void * data );
105 // chuck DLL query
106 typedef void ( CK_DLL_CALL * f_ck_addexport)( Chuck_DL_Query * query, const char * type, const char * name, f_ck_func addr, t_CKBOOL is_func );
107 typedef void ( CK_DLL_CALL * f_ck_addparam)( Chuck_DL_Query * query, const char * type, const char * name );
108 // functions for adding unit generators
109 typedef void ( CK_DLL_CALL * f_ck_ugen_add)( Chuck_DL_Query * query, const char * name, void * reserved );
110 typedef void ( CK_DLL_CALL * f_ck_ugen_extends)( Chuck_DL_Query * query, const char * parent ); //XXX - pld
111 typedef void ( CK_DLL_CALL * f_ck_ugen_func)( Chuck_DL_Query * query, f_ctor ctor, f_dtor dtor, f_tick tick, f_pmsg pmsg );
112 typedef void ( CK_DLL_CALL * f_ck_ugen_ctrl)( Chuck_DL_Query * query, f_ctrl ctrl, f_cget cget, const char * type, const char * name );
113 // set name
114 typedef void ( CK_DLL_CALL * f_ck_setname)( Chuck_DL_Query * query, const char * name );
116 // internal implementation header
117 extern "C" {
118 void CK_DLL_CALL __ck_addexport( Chuck_DL_Query * query, const char * type, const char * name, f_ck_func addr, t_CKBOOL is_func );
119 void CK_DLL_CALL __ck_addparam( Chuck_DL_Query * query, const char * type, const char * name );
120 void CK_DLL_CALL __ck_ugen_add( Chuck_DL_Query * query, const char * name, void * reserved );
121 void CK_DLL_CALL __ck_ugen_extends( Chuck_DL_Query * query, const char * parent); //XXX - pld
122 void CK_DLL_CALL __ck_ugen_func( Chuck_DL_Query * query, f_ctor ctor, f_dtor dtor, f_tick tick, f_pmsg pmsg );
123 void CK_DLL_CALL __ck_ugen_ctrl( Chuck_DL_Query * query, f_ctrl ctrl, f_cget cget, const char * type, const char * name );
124 void CK_DLL_CALL __ck_ugen_inherit( Chuck_DL_Query * query, const char * parent );
125 void CK_DLL_CALL __ck_setname( Chuck_DL_Query * query, const char * name );
128 // param conversion
129 #define GET_CK_FLOAT(ptr) (*(t_CKFLOAT *)ptr)
130 #define GET_CK_SINGLE(ptr) (*(float *)ptr)
131 #define GET_CK_DOUBLE(ptr) (*(double *)ptr)
132 #define GET_CK_INT(ptr) (*(t_CKINT *)ptr)
133 #define GET_CK_UINT(ptr) (*(t_CKUINT *)ptr)
134 #define GET_CK_TIME(ptr) (*(t_CKTIME *)ptr)
135 #define GET_CK_DUR(ptr) (*(t_CKDUR *)ptr)
136 #define GET_CK_STRING(ptr) (*(char **)ptr)
138 // param conversion with pointer advance
139 #define GET_NEXT_FLOAT(ptr) (*((t_CKFLOAT *&)ptr)++)
140 #define GET_NEXT_SINGLE(ptr) (*((float *&)ptr)++)
141 #define GET_NEXT_DOUBLE(ptr) (*((double *&)ptr)++)
142 #define GET_NEXT_INT(ptr) (*((t_CKINT *&)ptr)++)
143 #define GET_NEXT_UINT(ptr) (*((t_CKUINT *&)ptr)++)
144 #define GET_NEXT_TIME(ptr) (*((t_CKTIME *&)ptr)++)
145 #define GET_NEXT_DUR(ptr) (*((t_CKDUR *&)ptr)++)
146 #define GET_NEXT_STRING(ptr) (*((char * *&)ptr)++)
148 // param conversion
149 #define SET_CK_FLOAT(ptr,v) (*(t_CKFLOAT *&)ptr=v)
150 #define SET_CK_SINGLE(ptr,v) (*(float *&)ptr=v)
151 #define SET_CK_DOUBLE(ptr,v) (*(double *&)ptr=v)
152 #define SET_CK_INT(ptr,v) (*(t_CKINT *&)ptr=v)
153 #define SET_CK_UINT(ptr,v) (*(t_CKUINT *&)ptr=v)
154 #define SET_CK_TIME(ptr,v) (*(t_CKTIME *&)ptr=v)
155 #define SET_CK_DUR(ptr,v) (*(t_CKDUR *&)ptr=v)
156 #define SET_CK_STRING(ptr,v) (*(char *&)ptr=v)
158 // param conversion with pointer advance
159 #define SET_NEXT_FLOAT(ptr,v) (*((t_CKFLOAT *&)ptr)++=v)
160 #define SET_NEXT_SINGLE(ptr,v) (*((float *&)ptr)++=v)
161 #define SET_NEXT_DOUBLE(ptr,v) (*((double *&)ptr)++=v)
162 #define SET_NEXT_INT(ptr,v) (*((t_CKINT *&)ptr)++=v)
163 #define SET_NEXT_UINT(ptr,v) (*((t_CKUINT *&)ptr)++=v)
164 #define SET_NEXT_TIME(ptr,v) (*((t_CKTIME *&)ptr)++=v)
165 #define SET_NEXT_DUR(ptr,v) (*((t_CKDUR *&)ptr)++=v)
166 #define SET_NEXT_STRING(ptr,v) (*((char * *&)ptr)++=v)
169 //-----------------------------------------------------------------------------
170 // name: struct Chuck_DL_Proto
171 // desc: dynamic link proto
172 //-----------------------------------------------------------------------------
173 struct Chuck_DL_Proto
175 public: // these should not be used directly by the DLL
176 std::string name; // name of the thing
177 std::string type; // (return) type
178 t_CKBOOL is_func; // is a func?
179 std::vector<Chuck_Info_Param> params; // see Chuck_Info_Param in chuck_ugen.h
180 f_ck_func addr; // addr in the DLL
182 // constructor
183 Chuck_DL_Proto( const char * t = "", const char * n = "",
184 void * a = NULL, t_CKBOOL f = TRUE )
185 { type = t; name = n; addr = (f_ck_func)a, is_func = f; }
187 // clear proto
188 void clear()
189 { type = ""; name = ""; addr = NULL; params.clear(); }
191 // add a param
192 void add_param( const char * t, const char * n )
193 { params.push_back( Chuck_Info_Param( t, n ) ); }
199 //-----------------------------------------------------------------------------
200 // name: struct Chuck_DL_Query
201 // desc: dynamic link query
202 //-----------------------------------------------------------------------------
203 struct Chuck_DL_Query
205 public: // call these from the DLL
206 f_ck_addexport add_export; // call this to add export
207 f_ck_addparam add_param; // call this to add parameter to last export
208 f_ck_ugen_add ugen_add; // call this to add a ugen
209 f_ck_ugen_extends ugen_extends; // XXX - pld call this to extend another ugen
210 f_ck_ugen_func ugen_func; // call this (once) to set functions for last ugen
211 f_ck_ugen_ctrl ugen_ctrl; // call this (>= 0 times) to add ctrl to last ugen
212 f_ck_setname set_name; // call this to set name
214 const char * dll_name; // name of the DLL
215 void * reserved;
216 t_CKUINT srate; // sample rate
217 t_CKUINT bufsize; // buffer size
219 public: // these should not be used directly by the DLL
220 std::vector<Chuck_DL_Proto> dll_exports;
221 std::vector<Chuck_UGen_Info> ugen_exports;
222 int linepos;
224 // constructor
225 Chuck_DL_Query( );
227 // clear the query
228 void clear() { dll_exports.clear(); ugen_exports.clear(); }
234 //------------------------------------------------------------------------------
235 // name: union Chuck_DL_Return
236 // desc: dynamic link return function return struct
237 //------------------------------------------------------------------------------
238 union Chuck_DL_Return
240 t_CKINT v_int;
241 t_CKUINT v_uint;
242 t_CKFLOAT v_float;
243 char * v_string;
244 void * v_user;
246 Chuck_DL_Return() { memset( this, 0, sizeof(*this) ); }
252 //-----------------------------------------------------------------------------
253 // name: struct Chuck_DLL
254 // desc: dynamic link library
255 //-----------------------------------------------------------------------------
256 struct Chuck_DLL : public Chuck_VM_Object
258 public:
259 t_CKBOOL load( const char * filename, const char * func = CK_QUERY_FUNC,
260 t_CKBOOL lazy = FALSE );
261 t_CKBOOL load( f_ck_query query_func, t_CKBOOL lazy = FALSE );
262 void * get_addr( const char * symbol );
263 const char * last_error() const;
264 t_CKBOOL unload( );
266 t_CKBOOL good() const;
267 const Chuck_DL_Query * query( );
268 const Chuck_DL_Proto * proto( const char * symbol );
269 const Chuck_UGen_Info * ugen( const char * symbol );
271 Chuck_DLL( const char * id = NULL ) {
272 m_handle = NULL; m_done_query = FALSE;
273 this->init_ref();
274 m_id = id ? id : ""; m_query_func = NULL;
275 m_attach_func = NULL; m_detach_func = NULL; }
276 ~Chuck_DLL() {
277 this->unload(); }
279 protected:
280 void * m_handle;
281 std::string m_last_error;
282 std::string m_filename;
283 std::string m_id;
284 std::string m_func;
285 t_CKBOOL m_done_query;
287 f_ck_query m_query_func;
288 f_ck_attach m_attach_func;
289 f_ck_detach m_detach_func;
290 Chuck_DL_Query m_query;
291 std::map<std::string, Chuck_DL_Proto *> m_name2proto;
292 std::map<std::string, Chuck_UGen_Info *> m_name2ugen;
298 // dlfcn interface
299 #if defined(__MACOSX_CORE__)
300 #include <AvailabilityMacros.h>
301 #endif
303 // dlfcn interface, panther or below
304 #if defined(__MACOSX_CORE__) && MAC_OS_X_VERSION_MAX_ALLOWED <= 1030
306 #ifdef __cplusplus
307 extern "C" {
308 #endif
310 void * dlopen( const char * path, int mode );
311 void * dlsym( void * handle, const char * symbol );
312 const char * dlerror( void );
313 int dlclose( void * handle );
315 #define RTLD_LAZY 0x1
316 #define RTLD_NOW 0x2
317 #define RTLD_LOCAL 0x4
318 #define RTLD_GLOBAL 0x8
319 #define RTLD_NOLOAD 0x10
320 #define RTLD_SHARED 0x20 /* not used, the default */
321 #define RTLD_UNSHARED 0x40
322 #define RTLD_NODELETE 0x80
323 #define RTLD_LAZY_UNDEF 0x100
325 #ifdef __cplusplus
327 #endif
329 #elif defined(__WINDOWS_DS__)
331 #ifdef __cplusplus
332 extern "C" {
333 #endif
335 #define RTLD_LAZY 0x1
336 #define RTLD_NOW 0x2
337 #define RTLD_LOCAL 0x4
338 #define RTLD_GLOBAL 0x8
339 #define RTLD_NOLOAD 0x10
340 #define RTLD_SHARED 0x20 /* not used, the default */
341 #define RTLD_UNSHARED 0x40
342 #define RTLD_NODELETE 0x80
343 #define RTLD_LAZY_UNDEF 0x100
345 void * dlopen( const char * path, int mode );
346 void * dlsym( void * handle, const char * symbol );
347 const char * dlerror( void );
348 int dlclose( void * handle );
349 static char dlerror_buffer[128];
351 #ifdef __cplusplus
353 #endif
355 #else
356 #include "dlfcn.h"
357 #endif
362 #endif