From: Uno on
steve wrote:

> It is a float. In 'float *c, f;' the * is attached to 'c' not to
> float. You
> have essentially 'float *c; float f;'

Ok. I muffed the declaration of *f. In C, I believe its type is a
pointer to a float.

$ gcc -c -lm c_mm3.c -o caller.o
$ gfortran -c -Wall -Wextra f_mm3.f03 -o pass.o
$ gcc pass.o caller.o -lgfortran -o out
$ ./out
vector[0][0] is 0.785398
....
9.4601393 10.471128 11.480137
$ cat c_mm3.c
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define size1 5
#define size2 7
struct pass
{
int lenc, lenf;
float *c, *f;

};
void simulation (struct pass *arrays);
int
main ()
{

float vector[size1][size2];
int i, j;
struct pass arrays;

for (i = 0; i < size1; ++i)
for (j = 0; j < size2; ++j)
{
{
vector[i][j] = atan (1 + i + j) + i + j;
printf ("vector[%d][%d] is %f\n", i, j, vector[i][j]);
}
}

arrays.lenc = size1;
arrays.lenf = size2;
arrays.c = &vector[0][0];
arrays.f = NULL;

simulation (&arrays);
return 0;
}

// gcc -c -lm c_mm3.c -o caller.o
// gcc pass.o caller.o -lgfortran -o out
$ cat f_mm3.f03
subroutine simulation(arrays) bind(c)
use iso_c_binding
type, bind(c) :: pass
integer (c_int) :: lenc, lenf
type (c_ptr) :: c
real(c_float) :: f
end type pass
type (pass), intent(in) :: arrays
real (c_float), pointer :: c_array(:)
call c_f_pointer(arrays%c, c_array, &
& (/arrays%lenc*arrays%lenf/) )
print *, c_array
end subroutine simulation
! gfortran -c -Wall -Wextra f_mm3.f03 -o pass.o
$

But now I don't get it on the fortran side. Can someone say a few words
about what is and isn't happening with f and *f in this line:

real(c_float) :: f
--
Uno
From: Richard Maine on
Uno <merrilljensen(a)q.com> wrote:
....
> float *c, *f;
....
> type (c_ptr) :: c
> real(c_float) :: f

> But now I don't get it on the fortran side. Can someone say a few words
> about what is and isn't happening with f and *f in this line:
>
> real(c_float) :: f

This isn't exactly rocket science. The Fortran and C versions have to
be equivalent (the technical term is interoperable, but lets stick to
words more likely to be intuitive and say "equivalent".)

Even if you don't know the details, should it not be obvious that if the
C code declares c and f in the same way as each other, that the Fortran
code had also better declare them the same way as each other? Even if
you don't know exactly what the declarations should be, I would hope
that it ought to be obvious that they have to be the same. You have both
c and f declared the same way in the C code, but them completely
differently from each other in the Fortran code.

The "real(c_float) :: f" declares f to be a real of kind c_float. The
"type(c_ptr) :: f" declares f to be a pointer. If the C code declares f
to be a pointer and the Fortran code declares it to be a real, then it
ain't going to work. And yes, if you change the C code, you will have to
chang ethe Fortran code correspondingly.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
From: Uno on
Richard Maine wrote:
> Uno <merrilljensen(a)q.com> wrote:
> ...
>> float *c, *f;
> ...
>> type (c_ptr) :: c
>> real(c_float) :: f
>
>> But now I don't get it on the fortran side. Can someone say a few words
>> about what is and isn't happening with f and *f in this line:
>>
>> real(c_float) :: f
>

> Even if you don't know the details, should it not be obvious that if the
> C code declares c and f in the same way as each other, that the Fortran
> code had also better declare them the same way as each other? Even if
> you don't know exactly what the declarations should be, I would hope
> that it ought to be obvious that they have to be the same. You have both
> c and f declared the same way in the C code, but them completely
> differently from each other in the Fortran code.
>
> The "real(c_float) :: f" declares f to be a real of kind c_float. The
> "type(c_ptr) :: f" declares f to be a pointer. If the C code declares f
> to be a pointer and the Fortran code declares it to be a real, then it
> ain't going to work. And yes, if you change the C code, you will have to
> chang ethe Fortran code correspondingly.
>

Well I'm glad I caught your eye on this one, as I think it important in
an age when C routines might want to call fortran libraries having to do
with viscous flow at 8000 psi.

Such calls would need at least 3 dimensions, and I'll get to that soon,
if you don't include the fact that I have to build this weekend instead
of tap the keyboard.

Your book lies 3 feet from my knee, so if anything I ask can be resolved
there, I would be able to consult that. I've started into the chapter
on interoperability.

My simple question is whether everybody sees as many pointers as I do.
I'm convinced that I declared a pointer to float called f on the c side.
Why isn't it:

>>
>> real(c_float) :: *f

?

[re-ordered, for thematic reasons]
> This isn't exactly rocket science. The Fortran and C versions have to
> be equivalent (the technical term is interoperable, but lets stick to
> words more likely to be intuitive and say "equivalent".)

I heard the opinion last night that "we" need to economize on NASA, but
my considered opinion is that rocket science can describe what's coming
out of the BP Horizon disaster.
--
Uno
From: Richard Maine on
Uno <merrilljensen(a)q.com> wrote:

> Why isn't it:
> >>
> >> real(c_float) :: *f

I think the best answer is the one my dad would have given me 50 years
ago. Because.

One does not just transcribe C syntax into Fortran and expect it to
work. You have to use Fortran syntax. The * symbol is only used for 3
billion things in Fortran - not the 3 billion and 1 that would be the
case if it were also used to declare C pointers in Fortran.

C pointers are really very different from Fortran ones. No, I'm not
going to try to explain the differences. There are almost more
differences than similarities, and I'm not sure I needed the "almost"
there. In Fortran, you declare C pointers as type(c_ptr). Always (ok,
except for C function pointers, which use c_funptr). You don't declare
tham as Fortran pointers, and there wasn't a whole new Fortran syntax
invented for the purpose.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
From: nmm1 on
In article <1jlpvh4.cux2lq173mpqwN%nospam(a)see.signature>,
Richard Maine <nospam(a)see.signature> wrote:
>
>C pointers are really very different from Fortran ones. No, I'm not
>going to try to explain the differences. There are almost more
>differences than similarities, and I'm not sure I needed the "almost"
>there.

Snurrfl! Yes. Fortran pointers are really more like retargetable
ALLOCATABLE objects.

>In Fortran, you declare C pointers as type(c_ptr). Always (ok,
>except for C function pointers, which use c_funptr). You don't declare
>tham as Fortran pointers, and there wasn't a whole new Fortran syntax
>invented for the purpose.

To the OP: they're "void *" pointers, incidentally.

And, if you are an advanced C hacker, I recommend not playing too
many games with them. The Fortran interoperability chapter is a bit
sloppy about exactly what it supports in the way of pointer values.


Regards,
Nick Maclaren.
First  |  Prev  | 
Pages: 1 2
Prev: MR&C chp 14
Next: Runge-Kutta method for solving IVPs