[Top][All Lists]

[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*);
|       } else if (in.is_single_type()) {
|             const FloatComplexNDArray t = in.float_complex_array_value();
|             return (void*);
|         } 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

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


reply via email to

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