From help-octave-request at bevo dot che dot wisc dot edu Thu Aug 8 10:52:26 2002 Subject: Simple oct function From: "John W. Eaton" To: Iago Mosqueira Cc: help-octave at bevo dot che dot wisc dot edu Date: Thu, 8 Aug 2002 10:52:17 -0500 On 8-Aug-2002, Iago Mosqueira wrote: | Hello, | | I want to use some fortran subroutines from the GSLIB library in octave, | and I am attempting for the first time to write a C++ wrapper. After | reading the manual and a few other examples, I have the C++ and F77 | functions attached at the end. There is some simple clash between int | and octave_value_list, when I do | | mkoctfile addone.cpp -o addone.oct | | I get | | addone.cpp: In function `class octave_value_list Faddone(const | octave_value_list &, int)': | addone.cpp:13: `retval' cannot be used as a function | addone.cpp:13: implicit declaration of function `int addone(...)' | addone.cpp:13: warning: cannot pass objects of type `octave_value' | through `...' | /usr/include/octave-2.1.36/octave/oct-obj.h:173: | `octave_value_list::octave_value_list(int)' is private | addone.cpp:15: within this context | | what is the problem here? I know almost nothing about C++ and F77, but | if I could get this simple example running I would understand how to | make the real subroutines work. | | Many thanks | | | iago | | | addone.cpp | | #include | #include | #include | #include You probably want to avoid C headers in C++ files. Use and instead, and then only if actually needed. | extern "C" int Addone_ (int *, int *); If this is your Fortran routine, you probably want to use the F77_FUNC macros to handle possible upcasing and underscoring of the name: extern "C" int F77_FUNC (addone, ADDONE) (int*, int*); But, since your function below accepts scalars and only modifies the second arg, it might be better to write extern "C" int F77_FUNC (addone, ADDONE) (const int&, int&); Note that the value is not really returned from addone, but passed back in the second parameter. The int return type above is used because that works with most Unixy Fortran compilers, and it's also the way f2c works. If you have Fortran functions instead of subroutines, its much more reliable to wrap them in subroutines because different compilers use different conventions for returning values from functions. | DEFUN_DLD (addone, args, nargout, | "Addone") If you are not using nargout, you can omit it. | { | octave_value_list retval; If you only have one value to return, you can write octave_value retval; and Octave will automatically convert it to an octave_value_list with one element. | retval(0) = addone(args(0)); You probably want to do something like this: int x = args(0).int_value (); if (! error_state) { int result; F77_FUNC (addone, ADDONE) (x, result); retval = static_cast (result); } else error ("addone: expecting integer argument"); | return retval; | } | | | addone.f | | subroutine addone(x,y) | | integer x | integer y | y = 1 + x | return | end subroutine But to be reliable, you will probably also want to check that your function has been called with the correct number of arguments. Putting it all together: #include #include extern "C" int F77_FUNC (addone, ADDONE) (const int&, int&); DEFUN_DLD (addone, args, , "y = addone (x)") { octave_value retval; int nargin = args.length (); if (nargin == 1) { int x = args(0).int_value (); if (! error_state) { int result; F77_FUNC (addone, ADDONE) (x, result); retval = static_cast (result); } else error ("addone: expecting integer argument"); } else print_usage ("addone"); return retval; } jwe ------------------------------------------------------------- Octave is freely available under the terms of the GNU GPL. Octave's home on the web: http://www.octave.org How to fund new projects: http://www.octave.org/funding.html Subscription information: http://www.octave.org/archive.html -------------------------------------------------------------