Thank you very much. The changes you
suggested make a least the example program work properly. I will apply
these changes to my .oct file and let you know if it worked.
The information you supplied on argument
checking is also very useful for me.
Regards
Matthias
address@hidden schrieb am 05.07.2006 09:18:31:
> On 5-Jul-2006, address@hidden wrote:
>
> | ok, to make sure the same compiler was used for compiling octave
and
> | compiling my .oct file, I reinstalled octave from the sources.
> | The used compiler was g++ 4.0.4. The problem still occurs. I
hope the
> | attached bug report enables someone to track down the problem.
>
> OK, I had another look at your original code:
>
> #include <string>
> #include <octave/oct.h>
> #include <octave/ov-struct.h>
>
> DEFUN_DLD (conversionExample, prhs, nlhs ,
> "Reproduces an Error which does not occur when cygwin
is used")
> {
> double a;
> int b;
> std::string c;
> octave_value tmp;
> Octave_map::iterator p1;
>
> if ( !prhs(0).is_map() )
> {
> error("First input argument must be
of type struct.");
> return octave_value(0);
> }
>
> p1 = prhs(0).map_value().seek("a");
> tmp = prhs(0).map_value().contents(p1)(1);
> a = tmp.double_value();
> octave_stdout << "a is " <<
a << std::endl;
>
> p1 = prhs(0).map_value().seek("b");
> tmp = prhs(0).map_value().contents(p1)(2);
> b = tmp.int_value();
> octave_stdout << "b is " <<
b << std::endl;
>
> p1 = prhs(0).map_value().seek("c");
> tmp = prhs(0).map_value().contents(p1)(2);
> c = tmp.string_value().data();
> octave_stdout << "c is " <<
c << std::endl;
> return octave_value(0);
>
> }
>
> I think you are depending on temporaries existing longer than they
are
> required to.
>
> What happens if you try this instead:
>
> #include <string>
> #include <octave/oct.h>
> #include <octave/ov-struct.h>
>
> DEFUN_DLD (conversionExample, prhs, nlhs ,
> "Reproduces an Error which does not occur when cygwin
is used")
> {
> double a;
> int b;
> std::string c;
> octave_value tmp;
> Octave_map::iterator p1;
>
> if ( !prhs(0).is_map() )
> {
> error("First input argument must be
of type struct.");
> return octave_value(0);
> }
>
> Octave_map m = prhs(0).map_value();
>
> p1 = m.seek("a");
> tmp = m.contents(p1)(1);
> a = tmp.double_value();
> octave_stdout << "a is " <<
a << std::endl;
>
> p1 = m.seek("b");
> tmp = m.contents(p1)(2);
> b = tmp.int_value();
> octave_stdout << "b is " <<
b << std::endl;
>
> p1 = m.seek("c");
> tmp = m.contents(p1)(2);
> c = tmp.string_value().data();
> octave_stdout << "c is " <<
c << std::endl;
> return octave_value(0);
>
> }
>
> BTW, here is how I would write this function to check more carefully
> for invalid input (and avoid crashing Octave if the input is not what
> is expected):
>
> #include <octave/oct.h>
> #include <octave/oct-map.h>
>
> DEFUN_DLD (conversionExample, args, ,
> "Reproduces an Error which does not occur when
cygwin is used")
> {
> octave_value retval;
>
> if (args.length () > 0)
> {
> const Octave_map m = args(0).map_value ();
>
> if (! error_state)
> {
> // Might also check dimensions more carefully
here...
> int numel = m.numel ();
>
> if (numel == 3)
> {
> Cell tmp;
>
> tmp = m.contents ("a");
>
> if (! tmp.is_empty ())
> {
> double a = tmp(1).double_value
();
>
> if (! error_state)
> octave_stdout << "a
is " << a << std::endl;
> }
> else
> error ("struct field A not found");
>
> tmp = m.contents ("b");
>
> if (! tmp.is_empty ())
> {
> int b = tmp(2).int_value ();
>
> if (! error_state)
> octave_stdout << "b
is " << b << std::endl;
> }
> else
> error ("struct field B not found");
>
> tmp = m.contents ("c");
>
> if (! tmp.is_empty ())
> {
> std::string c = tmp(2).string_value
();
>
> if (! error_state)
> octave_stdout << "c
is " << c << std::endl;
> }
> else
> error ("struct field C not found");
> }
> else
> error ("expecting 3-element
struct array");
> }
> else
> error ("expecting argument to be a struct");
> }
> else
> error ("expecting one argument");
>
> return retval;
> }
>
> jwe