Prev: Correct way to write a wrapper for C functions that accept/return ??strings
Next: PGI Visual Fortran 2008 v10.3 with VS2008 Shell for Windows x86/x64
From: Phred Phungus on 9 Mar 2010 19:07 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 |