Arrays and Buffers¶
A number of C and C++ APIs take pointers to a buffer or an array. For example, from OpenCV a Mat
can be constructed like this:
data
is a pointer to a buffer consisting of rows x columns uint_8 values.
This API can be called in two ways from Ruby. The easiest way is to create a Ruby array and pass it to the constructor like this:
Rice will automatically convert the Ruby array to a C++ buffer using Array#pack
. The created buffer will be valid for the entirety of the call to C++. However, after that the buffer will be automatically deleted. If instead C++ should take ownership of the buffer, then use takeOwnership
as explained in the Memory Management section:
You can also create the buffer yourself and manage its lifetime as is appropriate:
To to this manually you will need to specify the correct pack
format string.
Using these techniques, Ruby can call almost any C/C++ API that takes a buffer made up of fundamental types (uint8_t, int8_t, uint16_t, int16_t, …. float, double…, etc).
In the case of a parameter that is void*
, you will have to use the buffer approach instead of the Array approach. That is because Rice will not be able to determine what pack
format string to use.
Array of Objects¶
C++ APIs can also take a pointer to an C array of objects. For example:
This code creates a view onto an existing Matrix based on an array of Range
objects. The length of the array is equal to the Matrix’s number of dimensions.
To call this from Ruby:
Array of Pointers¶
The above example also works with an array of pointers. In that case:
Notice the ranges
parameter is now a **
- or an array of pointers. You would call this method from Ruby in the exact same way as the example above.