[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Oct files: How to get read-only pointers to data for arguments of un
From: |
John W. Eaton |
Subject: |
Re: Oct files: How to get read-only pointers to data for arguments of unknown type? |
Date: |
Tue, 28 Feb 2012 09:10:54 -0500 |
On 28-Feb-2012, Stefan wrote:
| I figured out how to get a pointer to the data in an octave_value object,
| regardless of the type, without having octave make a copy:
|
| void *octGetData(const octave_value &in)
| {
| if (in.is_complex_type() && !in.is_scalar_type()) {
| // handle complex data types separately, but only if not scalar!
| if (in.is_double_type()) {
| const ComplexNDArray t = in.complex_array_value();
| return (void*) t.data();
| } else if (in.is_single_type()) {
| const FloatComplexNDArray t = in.float_complex_array_value();
| return (void*) t.data();
| } else {
| error("Data type not implemented.");
| return NULL;
| }
| } else {
| // handle bulk of data types with mex_get_data()
| return in.mex_get_data();
| }
| }
|
| So there is an octave_value method mex_get_data() that emulates Matlab's
| mxGetData() function, which handles most cases. For complex data types,
| mex_get_data() appears to make a copy of the data to emulate Matlab's
| behavior to return only the real part. This isn't what I wanted, since my
| library expects complex inputs in octave's storage order.
It has to make a copy because Octave stores complex values in a single
array with alternating real and imaginary parts but Matlab stores them
as two separate arrays, one for the real part and one for complex.
| I believe the above function does not interfere with octave's reference
| counting, so you can use it to pass arguments to an oct file by reference:
|
| DEFUN_DLD(oct_test, args, nargout, "Test")
| {
| void *data = octGetData(args(0));
| *(Complex*)data = Complex(7.,8.);
| return octave_value();
| }
|
| In octave:
|
| octave:1> x = 1+i
| x = 1 + 1i
| octave:2> oct_test(x)
| octave:3> x
| x = 7 + 8i
|
| Great, if the data in x fills up half of your computers memory and your
| point of writing an oct file in the first place was to have access to a fast
| C library that modifies your data in-place.
You are casting away const here, so you may see some unexpected
results.
For example, try
x = y = 1+i;
oct_test (x)
and I expect both x and y will change. This could cause a lot of
trouble for users of your code if they expect the semantics of
function calls in Octave to be consistent and NOT modify inputs to
functions.
jwe