help-octave
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Include Fortran Code which Returns Arrays of Dynamic/Unknown Size


From: John W. Eaton
Subject: Re: Include Fortran Code which Returns Arrays of Dynamic/Unknown Size
Date: Fri, 10 Oct 2008 16:50:24 -0400

On 10-Oct-2008, Marco2008 wrote:

| 
| 
| John W. Eaton wrote:
| > 
| > I don't know how to call this function from C/C++.
| > 
| > If you had a similar function in C++, for example something like
| > 
| >   void foo (double **v, int *len)
| >   {
| >     len = 10; // or some computed value
| >     *v = new double [len];
| > 
| >     // fill V here ...
| >   }
| > 
| > then you could call it from an Octave DEFUN like this:
| > 
| >   double *v;
| >   int len;
| >   foo (&v, &len);
| > 
| > and then copy the values from V to an appropriately sized Matrix
| > object:
| > 
| >   Matrix m (len, 1);
| >   double *pm = m.fortran_vec ();
| >   for (int i = 0; i < len; i++)
| >     m[i] = v[i];
| > 
| > then you would probably also want to free the memory allocated in FOO
| > to avoid a memory leak:
| > 
| >   delete [] v;
| > 
| > Is an allocatable array in Fortran some kind of object that carries
| > with it the size?  If so, then I think you need to know precisely what
| > your compiler does so that you can call a function like this from C++
| > (probably the details are implementation defined, so will not be
| > portable).  Or is it guaranteed to just be a pointer to some data?  If
| > it is just a pointer, then I think you will need to modify your
| > function so that it also returns the size.  Otherwise, how can a C++
| > function that calls your Fortran function know how large the allocated
| > array is?
| > 
| > jwe
| > _______________________________________________
| > Help-octave mailing list
| > address@hidden
| > https://www-old.cae.wisc.edu/mailman/listinfo/help-octave
| > 
| 
| Hello!
| Thanks for this idea.
| I tried a bit with this approach. It brought me to the following code:
| 
| subroutine funfortrantwo(size1, vector1)
|       implicit none
|       integer :: size1
|       real(8) :: vector1(size1)
|       vector1 = 2
|       ! write(6,*) vector1
| end subroutine funfortrantwo
| 
| #include <octave/oct.h>
| #include <iostream>
| #include "f77-fcn.h"
| extern "C"
| {
|       F77_RET_T
|       F77_FUNC (funfortrantwo, FUNFORTRANTWO) (int& n1, double* m1);
| }
| DEFUN_DLD (fun_cpp2, args, ,"...")
| {
|     octave_value_list retval;
|       double* m1;  
|       int n1 = 7;
|       F77_XFCN (funfortrantwo, FUNFORTRANTWO,
|                       ( n1, m1 ) );
|       if (f77_exception_encountered)
|       {
|               error ("Error!");
|               return retval;
|       }
|       int i1 = n1;
|       Matrix M1 (i1,1);
|       for (int i = 0; i < i1; i++)
|       {
|               double h1 = m1[i];
|               M1.fill(h1,i,0,i,0);
|       }
|       retval(0) = M1;
|       return retval;
| }
| 
| it can be compiled by mkoctfile. But inside octave I get:
| 
| panic: Segmentation fault -- stopping myself...
| attempting to save variables to `octave-core'...
| save to `octave-core' complete
| Segmentation fault
| 
| If I replace int  
|     int i1 = n1;
| by 
|    int i1 = 7;
| it works correctly for one time. The second time fails with the above
| mentioned panic. Maybe the  memory management in my c++-file is not correct.

|       double* m1;  
|       int n1 = 7;
|       F77_XFCN (funfortrantwo, FUNFORTRANTWO,
|                       ( n1, m1 ) );

No storage is allocated for m1.  You have only declared a pointer.
Octave crashes because the call to your Fortran function scribbles
over some memory.

Try

  int n1 = 7;
  Matrix mm1 (n1, 1);
  double *m1 = mm1.fortran_vec ();
  F77_XFCN (funfortrantwo, FUNFORTRANTWO, (n1, m1));

jwe


reply via email to

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