Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

ISO_C_BINDING, return a char* from C

4 views
Skip to first unread message

cyril giraudon

unread,
Jan 7, 2009, 1:28:55 PM1/7/09
to
Hello,

I thought it was easy but I don't succeed in return a char* from a C
function.

Given this C function declaration :

char* getName();

Please, what is the correct fortran interface ?
Could you give me a use case too ?

Thanks a lot,

Cyril.

James Van Buskirk

unread,
Jan 7, 2009, 2:59:29 PM1/7/09
to
"cyril giraudon" <cyril.g...@gmail.com> wrote in message
news:9a178acb-32d5-4280...@i20g2000prf.googlegroups.com...

> I thought it was easy but I don't succeed in return a char* from a C
> function.

> Given this C function declaration :

> char* getName();

> Please, what is the correct fortran interface ?
> Could you give me a use case too ?

C:\gfortran\clf\charstarex>type getName.c
/* File: getName.c */
char *x = "The Name You Get";

char * getName()
{
return x;
}
/* End of file: getName.c */

C:\gfortran\clf\charstarex>type charstarex.f90
! File: charstarex.f90
module ifaces
implicit none
interface
function getName() bind(C,name='getName')
use ISO_C_BINDING, only: C_PTR
implicit none
type(C_PTR) getName
end function getName
end interface
end module ifaces

program charstarex
use ifaces
use ISO_C_BINDING, only: C_CHAR, C_PTR, C_F_POINTER
implicit none
character(C_CHAR), pointer :: ptr(:)
integer i
type(C_PTR) cptr

cptr = getName()
i = 0
do
i = i+1
call C_F_POINTER(cptr, ptr, [i])
if(ptr(i) == achar(0)) exit
end do
write(*,*) ptr(1:size(ptr)-1)
end program charstarex
! End of file: charstarex.f90

C:\gfortran\clf\charstarex>gcc -Wall -c getName.c

C:\gfortran\clf\charstarex>gfortran -Wall charstarex.f90
getName.o -ocharstarex

C:\gfortran\clf\charstarex>charstarex
The Name You Get

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


Reinhold Bader

unread,
Jan 7, 2009, 2:59:03 PM1/7/09
to
Hello,

cyril giraudon schrieb:


> Hello,
>
> I thought it was easy but I don't succeed in return a char* from a C
> function.
>
> Given this C function declaration :
>
> char* getName();

since this is a function returning a pointer,

INTERFACE
function getname() bind(C, NAME='getName')
use, intrinsic :: ISO_C_BINDING
type(c_ptr) :: getname
end function
END INTERFACE

should do the job. To convert the result to a Fortran entity,
some juggling with C_F_POINTER() and maybe C_NULL_CHAR will be needed.
Since deferred length characters are not supported in most compilers
up to now, you'll probably have to make do with fixed length
character variables to store the result in.

Best Regards

cyril giraudon

unread,
Jan 9, 2009, 11:35:54 AM1/9/09
to
Thanks a lot Reinhold, It works fine.

Is is possible to do the same thing with the foollowing function
declaration :

void getName(char* name)

I've tried but I don't succeed in returning "name" :-(

Best Regards,

Cyril.

James Van Buskirk

unread,
Jan 13, 2009, 9:29:19 PM1/13/09
to
"cyril giraudon" <cyril.g...@gmail.com> wrote in message
news:ea9ba4e5-003c-4c37...@v18g2000pro.googlegroups.com...

> Is is possible to do the same thing with the foollowing function
> declaration :

> void getName(char* name)

> I've tried but I don't succeed in returning "name" :-(

C:\gfortran\clf\charstarex>type getName2.c
/* File: getName2.c */


char *x = "The Name You Get";

/* Note that we need char** to return a string; char* returns only
a single char */
void getName(char **name)
{
*name = x;
}
/* End of file: getName2.c */

C:\gfortran\clf\charstarex>type charstarex2.f90
! File: charstarex2.f90


module ifaces
implicit none
interface

subroutine getName(name) bind(C,name='getName')


use ISO_C_BINDING, only: C_PTR
implicit none

type(C_PTR) name
end subroutine getName


end interface
end module ifaces

program charstarex2


use ifaces
use ISO_C_BINDING, only: C_CHAR, C_PTR, C_F_POINTER
implicit none

! Correct mistake from last example: LEN comes before KIND for CHARACTER
character(len=1,kind=C_CHAR), pointer :: ptr(:)
integer i
type(C_PTR) cptr

call getName(cptr)


i = 0
do
i = i+1
call C_F_POINTER(cptr, ptr, [i])
if(ptr(i) == achar(0)) exit
end do
write(*,*) ptr(1:size(ptr)-1)

end program charstarex2
! End of file: charstarex2.f90

C:\gfortran\clf\charstarex>gcc -Wall -c getName2.c

C:\gfortran\clf\charstarex>gfortran -Wall charstarex2.f90
getName2.o -ocharstare
x2

C:\gfortran\clf\charstarex>charstarex2

cyril giraudon

unread,
Jan 15, 2009, 4:41:31 AM1/15/09
to
Thanks a lot James.

Best Regards

Cyril.

0 new messages