From: Phred Phungus on
James Van Buskirk wrote:

> C:\gfortran\clf\c_interop>type c_example.c

James' example works perfectly. A big part of the problem with interop
is figuring out which part is C and which part is fortran. I always
identify one as caller.


$ gcc -D_GNU_SOURCE -std=c99 -Wall -Wextra g2.c -c -o cfunc.o
$ ls
9vx-0.12 a1.c~ cfunc.o g1.c g2.c out
a1.c backups1 fortran_stuff g1.c~ g2.c~ unleashed

So far so good.

$ gfortran -D_GNU_SOURCE -Wall -Wextra caller1.f90 cfunc.o -o out
$ ./out
Testing
C test message
$ cat caller1.f90


module c_interop
implicit none
interface
subroutine cfunc1(str) bind(C,name='cfunc1')
use ISO_C_BINDING
implicit none
character(kind=C_CHAR) str(*)
end subroutine cfunc1
! gfortran doesn't allow the following. I think it should.
! subroutine cfunc1a(str) bind(C,name='cfunc1')
! use ISO_C_BINDING
! implicit none
! type(C_PTR), value :: str
! end subroutine cfunc1a
function cfunc2() bind(C,name='cfunc2')
use ISO_C_BINDING
implicit none
type(C_PTR) cfunc2
end function cfunc2
end interface
end module c_interop

program test
use ISO_C_BINDING
use c_interop
implicit none
character(len=10,kind=C_CHAR), target :: test_msg
character(kind=C_CHAR), pointer :: fp(:)
type(C_PTR) cp
integer i

test_msg = 'Testing'//achar(0)
call cfunc1(test_msg)
! call cfunc1a(C_LOC(test_msg(1:1)))
cp = cfunc2()
i = 1
do
call C_F_POINTER(cp,fp,[i])
if(fp(i) == achar(0)) exit
i = i+1
end do
call sub(fp,i-1)
contains
subroutine sub(p,j)
! I know the next line was wrong, but check out the error message you get
! character(kind=C_PTR) p(*)
character(kind=C_CHAR) p(*)
integer j
character(len=j) c

c = transfer(p(:j),c)
write(*,'(a)') c
end subroutine sub
end program test

! gfortran -D_GNU_SOURCE -Wall -Wextra caller1.f90 cfunc.o -o out
$ cat cfunc.c
cat: cfunc.c: No such file or directory
$ cat g2.c


#include <stdio.h>

char c[] = {'C',' ','t','e','s','t',' ','m','e','s','s','a','g','e','\0'};

void cfunc1(char* str)
{
printf("%s\n", str);
}

char *cfunc2(void)
{
return c;
}


// gcc -D_GNU_SOURCE -std=c99 -Wall -Wextra g2.c -c -o cfunc.o
$

As for this part:

! I know the next line was wrong, but check out the error message you get
! character(kind=C_PTR) p(*)

, gfortran has a lot to say:

$ gfortran -D_GNU_SOURCE -Wall -Wextra caller2.f90 cfunc.o -o out
caller2.f90:48.27:

character(kind=C_PTR) p(*)
1
Error: Syntax error in structure constructor at (1)
caller2.f90:53.24:

c = transfer(p(:j),c)
1
Error: Syntax error in argument list at (1)
caller2.f90:46.22:

subroutine sub(p,j)
1
Error: Symbol 'p' at (1) has no IMPLICIT type
caller2.f90:44.12:

call sub(fp,i-1)
1
Error: Type mismatch in argument 'p' at (1); passed CHARACTER(1) to UNKNOWN
$
--
fred