- <font color="#800000"><b>Reference</b></font> Read the web page <a href="http://cran.r-project.org/manuals.html" target="_blank">The R Manuals</a>. <br> The PDF document Writing R Extensions (Chapter 4) in The R Manuals (my mirror <a href="./reference/package/R-exts.pdf" target="_blank">here</a>). - <font color="#800000"><b>Call Fortran</b></font> First, create a Fortran code file "<a href="./example/R_Call/call_f.f" target="_blank">call_f.f</a>" contains this ``` c File name: call_f.f c For dynamical loading, compile by g77. c SHELL> g77 -c call_f.f ; g77 -shared -o call_f.so call_f.o subroutine hello(m, a, b, c, d) integer i, m real*8 a(m), b(m), c(m), d d = 0 do i = 1, m c(i) = a(i) + b(i) d = d + c(i) a(i) = 0 end do return end c Output is a shared library "call_f.so" can be called by R. ``` or for MS Windows will like this ``` c File name: call_f.f c For dynamical loading, compile by Compaq Visual Fortran. c Here, for fortran 77 syntex. subroutine hello(m, a, b, c, d) cDEC$ ATTRIBUTES DLLEXPORT::hello cDEC$ ATTRIBUTES C, REFERENCE, ALIAS:'hello_'::hello integer i, m real*8 a(m), b(m), c(m), d d = 0 do i = 1, m c(i) = a(i) + b(i) d = d + c(i) a(i) = 0 end do return end c Output is a shared library "call_f.dll" can be called by R. c For fortran 90 syntex, use "!DEC$" to replace "cDEC$". ``` Create an R code file "<a href="./example/R_Call/call_f.r" target="_blank">call_f.r</a>" contains this ``` # File name: call_f.r dyn.load("call_f.so") # For MS Windows, it will be like this # dyn.load("C:/Windows/Desktop/call_f.dll") symbol.For("hello") is.loaded(symbol.For("hello")) a <- 1 : 9 test.f <- function(a) { b <- a d <- vector(mode = "numeric", length = length(a)) e <- vector(mode = "numeric", length = 1) ret <- .Fortran("hello", m = length(a), a = as.double(a), b = as.double(b), d = as.double(d), e = as.double(e)) ret } test.f(a) dyn.unload("call_f.so") # For MS Windows, it will be like this # dyn.unload("C:/Windows/Desktop/call_f.dll") ``` - <font color="#800000"><b>More about C for MS Windows</b></font> In MS Windows you can use Compaq Visual Fortran to compile call_f.f as call_f.dll and the dll can be called by R.<br> See the detail in <a href="http://www.stats.uwo.ca/faculty/murdoch/software/compilingDLLs/fortran.html" target="_blank"> Using Fortran with R in Windows</a> (my mirror <a href="./reference/stats/fortran.html" target="_blank">here</a>). <br> About mixed language, see <a href="http://home.t-online.de/home/markus.faust/Softwareentwicklung/mixed_lang_progr.htm" target="_blank"> Markus Faust's mixed language programing</a> (my mirror <a href="./reference/mixed_lang_progr.htm" target="_blank">here</a>). <br> For testing, you can download my compiled example "<a href="./example/R_Call/call_f.dll" target="_blank">call_f.dll</a>" to "C:\Windows\Desktop\". - <font color="#800000"><b>Call C</b></font> First, create an C code file "<a href="./example/R_Call/call_c.c" target="_blank">call_c.c</a>" contains this ``` /* File name: call_c.c For dynamical load compile by gcc. SHELL> gcc -c call_c.c ; gcc -shared -o call_c.so call_c.o */ void hello(int m, double *a, double *b, double *c, double *d){ int i; d = 0; for(i = 0; i < m; i++){ c[i] = a[i] + b[i]; *d =+ c[i]; a[i] = 0; } } /* Output is a shared library "call_c.so" can be called by R. */ ``` Create an R code file "<a href="./example/R_Call/call_c.r" target="_blank">call_c.r</a>" contains this ``` # File name: call_c.r dyn.load("call_c.so") # For MS Windows, it will be like this # dyn.load("C:/Windows/Desktop/call_c.dll") symbol.C("hello") is.loaded(symbol.C("hello")) a <- 1 : 9 test.c <- function(a) { b <- a d <- vector(mode = "numeric", length = length(a)) e <- vector(mode = "numeric", length = 1) ret <- .C("hello", m = length(a), a = as.double(a), b = as.double(b), d = as.double(d), e = as.double(e)) ret } test.c(a) dyn.unload("call_c.so") # For MS Windows, it will be like this # dyn.unload("C:/Windows/Desktop/call_c.dll") ``` - <font color="#800000"><b>More about C for MS Windows</b></font> In MS Windows you can use C++Builder to compile "call_c.c" as "call_c.dll" and the dll can be called by R. <br> See the detail in <a href="http://www.dfu.min.dk/uht/Software/DLL/" target="_blank">Uffe's DLL example</a> (my mirror <a href="./reference/dfu/" target="_blank">here</a>). <br> For testing, you can download my compiled example "<a href="./example/R_Call/call_c.dll" target="_blank">call_c.dll</a>" to "C:\Windows\Desktop\". - <font color="#800000"><b>Output</b></font> ``` $m [1] 9 $a [1] 0 0 0 0 0 0 0 0 0 $b [1] 1 2 3 4 5 6 7 8 9 $d [1] 2 4 6 8 10 12 14 16 18 $e [1] 90 ``` - <font color="#800000"><b>Conclusion</b></font> - Call by address in Fortran. - Call by value in C. - Call by value in R function. - <font color="red">Call by address for R external??</font> <br> The function <code>.C()</code> and <code>.Fortran()</code> have a default option "<font color="red">DUP = TRUE</font>" which will copy the object in R and pass the address of duplication to C. If you know how to handle the memory carefully in C, you can set "<font color="blue">DUP = FALSE</font>" which will directly pass the address to C without duplication. - See the section "<a href="./call_Robj.html">C Call R Objects</a>". - <font color="#800000"><b>More</b></font> About Fortran and C, you can read the chapter 16 in <a href="http://www.insightful.com/" target="_blank">S-Plus</a> 2000 Programer's Guide (my mirror <a href="./reference/pguide.pdf" target="_blank">here</a>). For MS Windows users, you can read this, <a href="http://www.stats.uwo.ca/faculty/murdoch/software/compilingDLLs/index.html" target="_blank"> Using external compilers with R in Windows</a> (my mirror <a href="./reference/stats/index.html" target="_blank">here</a>). <br> For calling other computer languages, such as Tcl/Tk, Java, Perl, Python, ... etc, see <a href="http://www.omegahat.org/" target="_blank">omegahat</a> for detail. --- <div w3-include-html="../preamble_tail_date.html"></div>