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
23 -----------------------------------------------------------------------------*/
25 //-----------------------------------------------------------------------------
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
34 //-----------------------------------------------------------------------------
35 #ifndef __CHUCK_DL_H__
36 #define __CHUCK_DL_H__
38 #include "chuck_def.h"
40 #include "chuck_ugen.h"
48 // chuck dll export linkage and calling convention
50 #if defined (__PLATFORM_WIN32__)
51 #define CK_DLL_LINKAGE extern "C" __declspec( dllexport )
53 #define CK_DLL_LINKAGE extern "C"
56 #if defined(__WINDOWS_DS__)
57 #define CK_DLL_CALL _cdecl
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)
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
);
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
);
114 typedef void ( CK_DLL_CALL
* f_ck_setname
)( Chuck_DL_Query
* query
, const char * name
);
116 // internal implementation header
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
);
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)++)
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
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
; }
189 { type
= ""; name
= ""; addr
= NULL
; params
.clear(); }
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
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
;
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
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
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;
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
;
274 m_id
= id
? id
: ""; m_query_func
= NULL
;
275 m_attach_func
= NULL
; m_detach_func
= NULL
; }
281 std::string m_last_error
;
282 std::string m_filename
;
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
;
299 #if defined(__MACOSX_CORE__)
300 #include <AvailabilityMacros.h>
303 // dlfcn interface, panther or below
304 #if defined(__MACOSX_CORE__) && MAC_OS_X_VERSION_MAX_ALLOWED <= 1030
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
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
329 #elif defined(__WINDOWS_DS__)
335 #define RTLD_LAZY 0x1
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];