Pointers¶
C++ makes heavy use of pointers. In general, C++ pointers point to objects which Rice wraps as Ruby objects.
However, this is not always the case. As described in the type mapping section, pointers may also point to:
- Fundamental types (example,
int*) - Array of objects (example,
int[]orMyClass[]) - Array of pointers (example
int**orMyClass**)
In these case, Rice uses Pointer<T> and Buffer\<T> Ruby classes to enable Ruby code to manipulate them. In some cases these classes can be auto generated by Rice and in others you must tell Rice to generate them. These cases are explained below.
The Pointer<T> classes have very little functionality - they simply wrap C++ pointers. This allows them to be passed to C++ APIs that take pointers. They also define a single method, buffer, which returns the appropriate Ruby Buffer<T> class.
Buffer<T> classes enable Ruby to manipulate the memory pointed to by a pointer. They can also create new C++ pointers from Ruby objects.
Fundamental Types¶
It is common for C and C++ APIs to take pointers to blocks of memory consisting of fundamental types such as unsigned chars. For example, the OpenCV library includes an API to create a Mat instance like this:
data is a pointer to a buffer consisting of uint_8 values.
Rice automatically detects these types of pointers and generates Pointer and Buffer Ruby classes. For example, for a pointer to an int, int*, Rice will create the Ruby classes Rice::Pointer≺int≻ and Rice::Buffer≺int≻.
Array of Objects¶
C++ APIs can also take a pointer to an 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.
Rice cannot distinguish this case from a normal pointer, thus you must tell it that ranges is a pointer to an array of objects. This is done using the ArgBuffer class:
If a C++ method or function returns a buffer then you must tell Rice that by using the ReturnBuffer class:
Range* Matrix::ranges(const int row)
Data_Type<Matrix> rb_cMatrix =
.define_method("call", &Matrix::operator(), ReturnBuffer());
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.
Rice automatically detects these types of pointers and generates Pointer and Buffer Ruby classes. For example, for a pointer to an int, int**, Rice will create the Ruby classes Rice::Pointer≺int∗≻ and Rice::Buffer≺int∗≻.