|
2 | 2 | # Max C API Notes
|
3 | 3 |
|
4 | 4 |
|
| 5 | +## Memory management |
| 6 | + |
| 7 | +```c |
| 8 | +char *ptr; |
| 9 | +char **hand; |
| 10 | +ptr = sysmem_newptr(2000); |
| 11 | +post("I have a pointer %lx and it is %ld bytes in size",ptr, sysmem_ptrsize(ptr)); |
| 12 | +ptr = sysmem_resizeptrclear(ptr, 3000); |
| 13 | +post("Now I have a pointer %lx and it is %ld bytes in size",ptr, |
| 14 | + sysmem_ptrsize(ptr)); |
| 15 | +sysmem_freeptr(ptr); |
| 16 | +hand = sysmem_newhandle(2000); |
| 17 | +post("I have a handle %lx and it is %ld bytes in size",hand, |
| 18 | + sysmem_handlesize(hand)); |
| 19 | +sysmem_resizehandle(hand, 3000); |
| 20 | +post("Now the handle %lx is %ld bytes in size",hand, sysmem_ptrsize(hand)); |
| 21 | +sysmem_freehandle(hand); |
| 22 | +``` |
| 23 | +
|
| 24 | +## Typed vs Untyped Methods |
| 25 | +
|
| 26 | +
|
| 27 | +
|
| 28 | +
|
| 29 | +
|
| 30 | +
|
| 31 | +
|
| 32 | +
|
| 33 | +
|
| 34 | +
|
| 35 | +This is from the Max API docs: |
| 36 | +
|
| 37 | +Max objects, such as the one you write, are C data structures in which methods are dynamically bound to functions. Your object's methods are called by Max, but your object can also call methods itself. When you call a method, it is |
| 38 | +essential to know whether the method you are calling is typed or not. |
| 39 | +
|
| 40 | +Calling a typed method requires passing arguments as an array of atoms. Calling an untyped method requires that you know the exact arguments of the C function implementing the method. In both cases, you supply a symbol that names the method. |
| 41 | +
|
| 42 | +In the typed method case, Max will take the array of atoms and pass the arguments to the object according to the method's argument type specifier list. For example, if the method is declared to have an argument type specifier list of A_LONG, 0, the first atom in the array you pass will be converted to an int and passed to the function on the stack. If there are no arguments supplied, invoking a typed method that has A_LONG, 0 as an argument type specifier will fail. To make typed method calls, use `object_method_typed()` or `typedmess()`. |
| 43 | +
|
| 44 | +In the untyped method case, Max merely does a lookup of the symbol in the object, and, if a matching function is found, calls the function with the arguments you pass. |
| 45 | +Certain methods you write for your object, such as the assist method for describing your object and the DSP method in audio objects, are declared as untyped using the A_CANT argument type specifier. This means that Max will not typecheck the arguments you pass to these methods, but, most importantly, a user cannot hook up a message box to your object and send it a message to invoke an untyped method. (Try this for yourself – send the assist message to a standard Max object.) |
| 46 | +
|
| 47 | +When you use an outlet, you're effectively making a typed method call on any objects connected to the outlet. |
| 48 | +
|
| 49 | +
|
| 50 | +
|
| 51 | +
|
5 | 52 |
|
6 | 53 | ## Sending arbitrary messages to an object
|
7 | 54 |
|
| 55 | +
|
| 56 | +
|
| 57 | +
|
| 58 | +
|
8 | 59 | In https://cycling74.com/forums/error-handling-with-object_method_typed, there is a need to figure the type of the method which is being called in sending.
|
9 | 60 |
|
10 | 61 |
|
@@ -162,6 +213,67 @@ In this example since the message "clear" has no arguments the typed/untyped dis
|
162 | 213 |
|
163 | 214 | ### ext_obex.h
|
164 | 215 |
|
| 216 | +For Untyped Methods (A_CANT) |
| 217 | +
|
| 218 | +```c |
| 219 | +
|
| 220 | +/** |
| 221 | + Sends an untyped message to an object. |
| 222 | + There are some caveats to its use, however, particularly for 64-bit architectures. |
| 223 | + object_method_direct() should be used in cases where floating-point or other non-integer types are being passed on the stack or in return values. |
| 224 | +
|
| 225 | + @ingroup obj |
| 226 | +
|
| 227 | + @param x The object that will receive the message |
| 228 | + @param s The message selector |
| 229 | + @param ... Any arguments to the message |
| 230 | +
|
| 231 | + @return If the receiver object can respond to the message, object_method() returns the result. Otherwise, the function will return 0. |
| 232 | +
|
| 233 | + @remark Example: To send the message <tt>bang</tt> to the object <tt>bang_me</tt>: |
| 234 | + @code |
| 235 | + void *bang_result; |
| 236 | + bang_result = object_method(bang_me, gensym("bang")); |
| 237 | + @endcode |
| 238 | +*/ |
| 239 | +
|
| 240 | +void *object_method(void *x, t_symbol *s, ...); |
| 241 | +
|
| 242 | +/** |
| 243 | + do a strongly typed direct call to a method of an object |
| 244 | +
|
| 245 | + @ingroup obj |
| 246 | +
|
| 247 | + |
| 248 | + @param rt The type of the return value (double, void*, void...) |
| 249 | + @param sig the actual signature of the function in brackets ! |
| 250 | + something like (t_object *, double, long) |
| 251 | + @param x The object where the method we want to call will be looked for, |
| 252 | + it will also always be the first argument to the function call |
| 253 | + @param s The message selector |
| 254 | + @param ... Any arguments to the call, the first one will always be the object (x) |
| 255 | +
|
| 256 | + @return will return anything that the called function returns, typed by (rt) |
| 257 | + |
| 258 | + @remark Example: To call the function identified by <tt>getcolorat</tt> on the object <tt>pwindow</tt> |
| 259 | + which is declared like: |
| 260 | + t_jrgba pwindow_getcolorat(t_object *window, double x, double y) |
| 261 | + @code |
| 262 | + double x = 44.73; |
| 263 | + double y = 79.21; |
| 264 | + t_object *pwindow; |
| 265 | + t_jrgba result = object_method_direct(t_jrgba, (t_object *, double, double), pwindow, gensym("getcolorat"), x, y); |
| 266 | + @endcode |
| 267 | +*/ |
| 268 | + |
| 269 | +#define object_method_direct(rt, sig, x, s, ...) ((rt (*)sig)object_method_direct_getmethod((t_object *)x, s))(object_method_direct_getobject((t_object *)x, s), __VA_ARGS__) |
| 270 | +
|
| 271 | +method object_method_direct_getmethod(t_object *x, t_symbol *sym); |
| 272 | +void *object_method_direct_getobject(t_object *x, t_symbol *sym); |
| 273 | +``` |
| 274 | + |
| 275 | + |
| 276 | +For Typed Methods (A_GIMME) |
165 | 277 | ```c
|
166 | 278 | /**
|
167 | 279 | Sends a type-checked message to an object.
|
|
0 commit comments