Prev: Flowchart software
Next: GUI: Fortran + Visual Basic
From: Eli Osherovich on 9 Mar 2010 02:04 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 9 Mar 2010 08:18 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 9 Mar 2010 10:51 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 9 Mar 2010 10:53 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 9 Mar 2010 11:47
"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 |