Use another language to call a function: Difference between revisions

→‎{{header|TXR}}: Notes about preparation of data.
(→‎{{header|TXR}}: Notes about preparation of data.)
Line 1,118:
 
Note that the obvious way of passing a <code>size_t</code> value by pointer, namely <code>(ptr size-t)</code> doesn't work. While the callback will receive the size (FFI will decode the pointer type's semantics and get the size value), updating the size will not propagate back to the caller, because it becomes, effectively, a by-value parameter. A <code>(ptr size-t)</code> object has to be embedded in an aggregate that is passed by reference, in order to have two-way semantics. Here we use the trick of treating the <code>size_t *</code> as an array of 1, which it ''de facto'' is. In the callback, we establish local symbol macro which lets us just refer to <code>[sizeptr 0]</code> it as <code>size</code>.
 
Note also how the data is prepared. As a special case, FFI creates a correspondence between the <code>char</code> array and a character string. The callback must mutate the character string to the desired value; FFI will then propagate the mutation to the original array. If the callback mistakenly performed <code>(set data s)</code>, it wouldn't work, because the original string object is untouched. Only the lexical <code>data</code> variable is replaced with a pointer <code>s</code>. The expression <code>(set [data :..:] s)</code> replaces a subrange of <code>data</code> with <code>s</code>, where the subrange is all of <code>data</code>.
 
But our approach has a problem: it uses FFI in a way that relies on knowing the size of the C object, which is incorrect. The C buffer could be of any size; the only indicator we can trust is the run-time value we are given.
543

edits