help-octave
[Top][All Lists]
Advanced

[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


reply via email to

[Prev in Thread] Current Thread [Next in Thread]