From: Eli Osherovich on
What is the correct way to write a wrapper for C functions that accept/
return strings.

For example

void cfunc1(char* str)
char * cfunc2(void)

Thank you.
From: Malcolm McLean on


Phred Phungus wrote:
> Eli Osherovich wrote:
> > What is the correct way to write a wrapper for C functions that accept/
> > return strings.
> >
> > For example
> >
> > void cfunc1(char* str)
> > char * cfunc2(void)
> >
>
Acceting a string is easy. Just accept a char * or a const char * to a
nul-terminated string.

Returning strings you have to make a judgement call. Sometimes it is
easier for caller to pass you a char * to a buffer which he controls,
sometimes it is easier to return a char * containing allocated data.
(Just rarely you want to retrn a char * to a static buffer). The fisrt
method is likely to be faster and doesn't depend on malloc(), the
second method is much less likely to allow a buffer overflow, and may
the the only practical method if the length of the return string can't
be predicted in advance.
From: Eli Osherovich on
On Mar 9, 9:55 am, James Tursa <aclassyguywithakno...(a)hotmail.com>
wrote:

>
> Does your compiler support C Interop, or do you need another method
> (e.g., using %REF) ?

Sorry, I did not mention it.

I want to be as close to standard as possible. It can be assumed that
the compiler supports all C interoperability features defined by
F2003.

Thank you.



From: Eli Osherovich on
On Mar 9, 3:18 pm, Malcolm McLean <malcolm.mcle...(a)btinternet.com>
wrote:
> Phred Phungus wrote:
> > Eli Osherovich wrote:
> > > What is the correct way to write a wrapper for C functions that accept/
> > > return strings.
>
> > > For example
>
> > > void cfunc1(char* str)
> > > char * cfunc2(void)
>
> Acceting a string is easy. Just accept a char * or a const char * to a
> nul-terminated string.
>
> Returning strings you have to make a judgement call. Sometimes it is
> easier for caller to pass you a char * to a buffer which he controls,
> sometimes it is easier to return a char * containing allocated data.
> (Just rarely you want to retrn a char * to a static buffer). The fisrt
> method is likely to be faster and doesn't depend on malloc(), the
> second method is much less likely to allow a buffer overflow, and may
> the the only practical method if the length of the return string can't
> be predicted in advance.

May be I do not understand you correctly... but my impression is you
are talking about C not Fortran.

From: James Van Buskirk on
"Eli Osherovich" <eli.osherovich(a)gmail.com> wrote in message
news:3754018c-22d7-446f-95ed-f1053f08587c(a)g11g2000yqe.googlegroups.com...

> > > What is the correct way to write a wrapper for C functions that
> > > accept/
> > > return strings.

> > > For example

> > > void cfunc1(char* str)
> > > char * cfunc2(void)

> May be I do not understand you correctly... but my impression is you
> are talking about C not Fortran.

C:\gfortran\clf\c_interop>type c_example.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;
}

C:\gfortran\clf\c_interop>type c_interop.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

C:\gfortran\clf\c_interop>gcc -Wall -c c_example.c

C:\gfortran\clf\c_interop>gfortran -Wall c_interop.f90
c_example.o -oc_interop

C:\gfortran\clf\c_interop>c_interop
Testing
C test message

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


 |  Next  |  Last
Pages: 1 2
Prev: Flowchart software
Next: GUI: Fortran + Visual Basic