Hi, I've been trying to pass a character vector from R to a FORTRAN subroutine. There have been several posts discussing this issue (e.g. http://tolstoy.newcastle.edu.au/R/help/98a/0547.html, http://tolstoy.newcastle.edu.au/R/help/05/10/13558.html, http://tolstoy.newcastle.edu.au/R/help/01a/2577.html, http://tolstoy.newcastle.edu.au/R/help/01c/1795.html, http://tolstoy.newcastle.edu.au/R/devel/03a/0620.html, http://tolstoy.newcastle.edu.au/R/devel/99b/0323.html). According to R-exts (section 5.2, Interface functions .C and .Fortran), there are severe limitations on this: "Only the first element of the character vector is passed in, as a fixed-length (255) character array".
I think there may be a work-around, although I'm no FORTRAN expert, and I would like to hear your thoughts about it. The basic idea is to convert the strings to integers, transfer the resulting integer vector to FORTRAN, and then convert back to characters. Here's an example: ####### start of fortran code subroutine readchar(intstring,stringlengths,totalnchar,nstrings) implicit none C global variables integer totalnchar,nstrings integer intstring(totalnchar),stringlengths(nstrings) C local variables integer j,count, stringLength, i1, i2 parameter(stringLength = 1000) character c*(stringLength) C functions, etc. intrinsic char,min c convert from integer to character do j = 1,min(stringLength,totalnchar) write(c(j:j),'(A)') char(intstring(j)) end do count=0 do j = 1,nstrings i1 = (count+1) i2 = min(count+stringlengths(j),stringLength) c print the jth string write(*,*) c(i1:i2) c add a blank line after it write(*,*) count = count+stringlengths(j) c avoid reading past the bounds of the character variable if(count .ge. stringLength) then goto 10 end if end do 10 continue return end ####### end of fortran code ####### start of R code strings <- c("donald duck", "When trying to express oneself, it's frankly quite absurd, To leaf through lengthy lexicons to find the perfect word. A little spontaniaty keeps conversation keen, You need to find a way to say, precisely what you mean... Supercalifragilisticexpialidocious! Even though the sound of it is something quite atrosicous! If you say it loud enough, you'll always sound precocious", " !\"#$%&'()*+,-./0123456789:;<=>?...@abcdefghijklmnopqrstuvwxyz[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~") system('R CMD SHLIB readchar.f') dyn.load('readchar.so') A <- .Fortran('readchar', as.integer(unlist(sapply(strings,charToRaw),use.names=FALSE)), as.integer(nchar(strings)), as.integer(sum(nchar(strings))), as.integer(length(strings))) dyn.unload('readchar.so') ####### end of R code Running this gives: > strings <- c("donald duck", + "When trying to express oneself, it's frankly quite absurd, + To leaf through lengthy lexicons to find the perfect word. + A little spontaniaty keeps conversation keen, + You need to find a way to say, precisely what you mean... + Supercalifragilisticexpialidocious! + Even though the sound of it is something quite atrosicous! + If you say it loud enough, you'll always sound precocious", + " !\"#$%&'()*+,-./0123456789:;<=>?...@abcdefghijklmnopqrstuvwxyz[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~") > > system('R CMD SHLIB readchar.f') g77 -fpic -g -O2 -c readchar.f -o readchar.o gcc -std=gnu99 -shared -L/usr/local/lib64 -o readchar.so readchar.o -lg2c -lm > > dyn.load('readchar.so') > A <- .Fortran('readchar', + as.integer(unlist(sapply(strings,charToRaw),use.names=FALSE)), + as.integer(nchar(strings)), + as.integer(sum(nchar(strings))), + as.integer(length(strings))) donald duck When trying to express oneself, it's frankly quite absurd, To leaf through lengthy lexicons to find the perfect word. A little spontaniaty keeps conversation keen, You need to find a way to say, precisely what you mean... Supercalifragilisticexpialidocious! Even though the sound of it is something quite atrosicous! If you say it loud enough, you'll always sound precocious !"#$%&'()*+,-./0123456789:;<=>?...@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ > > dyn.unload('readchar.so') > One obvious weakness is that you have to specify in advance the maximum number of characters that can be passed to the subroutine. Another possible problem is that this maximum may be also be rather limited (e.g. one fortran 77 guide says that it is system-dependent, and while 255 characters should be safe, many systems allow up to 32767 characters: http://www.star.le.ac.uk/~cgp/prof77.html#tth_sEc5.1). Despite these weaknesses, it looks like (at least on some systems) it is possible to pass character vectors to FORTRAN subroutines, avoiding the restrictions suggested in R-Exts. In the above example, several strings are passed to the subroutine, and one of them is longer than the 255 character limit (as noted in R-Exts). It also suggests obvious ways character data can be passed back into R. But I admit, it is a bit of a hack... Jeremy Silver [[alternative HTML version deleted]] ______________________________________________ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.