[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Oct files: How to get readonly pointers to data for arguments of un
From: 
John W. Eaton 
Subject: 
Re: Oct files: How to get readonly pointers to data for arguments of unknown type? 
Date: 
Tue, 28 Feb 2012 09:10:54 0500 
On 28Feb2012, 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 inplace.
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