| Home | News | Site Search | E-mail Search | A-Z | Directories | Contact | |||||||||||
![]() |
Acadia Centre for Mathematical Modelling and Computation | ||||||||||
|
Calling C Functions From RWhile it is generally recommended that when you integrate C code into R, you should package and install it as an R library (optionally releasing it to the public), you will often want to first test to see if your code even works before packaging, and sometimes you may just want to run the C code from R a few times, and not worry about packaging it properly for re-use by you or others later. This particular page shows how to compile C code and call it from R directly without setting up an R package. Details on setting up an R package are described elsewhere. Steps to Profiling a Program
1. Obtain or write C codeUsually, you're either writing new C code, or have existing C code you wish to call from R. You only need a copy of this code. For purposes of this example, we will implement a factorial function, as follows (assuming the code is in a file called 'factorial.c'): 2. Write wrapper C functions if necessaryThere are strict constraints on what types of functions R can call. These include:
Because the function above breaks one (actually, both) of the above rules, we must write a wrapper function which complies with R's rules, and which calls our desired function. We'll call it factorial_R_wrapper, and place it in the file wrapper.c: Notice that all input and output parameters are pointers to data 3. Compile the C code into a shared libraryR only works with shared libraries (DLL's on Windows, .so files on Unix). This tutorial will show the Unix method for two reasons:
To compile multiple files into a shared library, you can run: Please note - there are periodic differences between different machines and OS's. Sometimes -fPIC is not required (it is on Linux/Opteron). Usually, it works with -fPIC, and sometimes without. There are other possible options that could be required, but in 99% of situations, the above will do the job. Now we have a shared library called factorial.so, which supplies a function called factorial_R_wrapper which can be called by R. 4. Write an R wrapper functionR's interface for calling C functions is not the way you or anyone else will want to call the function in R. The best option is to write a small R function to act as a more convenient wrapper. Following our example, we would want an R function similar to: This R function first makes sure the C function called factorial_R_wrapper is loaded by testing if the function is currently loaded, and if not, loads the library it is in. Then, it calls the function. .C() calls a C function. The name is the first argument. The rest of the arguments are to be passed to the C function, and must be in the same order as they appear in the C function. Notice the difference between the input parameter n, and the output parameter result. The input parameter is prepared using as.integer. The "as" functions convert from R data formats to C data formats. There are as.double, as.integer, and several other like them. The output parameter is given as integer(1), which means "make space for 1 C integer." double(10) would mean "provide space to 10 C double values." Stylistically, you should give names to at least all of your output parameters. If the parameter has a name, the list that is returned by .C will have that parameter's value as an element by that name. That it why saying returned_data$result works to return the value in the result, or 2nd, parameter. It's easiest to put this R code in its own file, which we'll call 'factorial.R'. 5. Use your R wrapper functionNow to use your function in an R session or program, you only need to source() your R file, and use the R function created in the previous step. For example: And the copy of such a session should include: Wrap-UpCalling C functions from R is a relatively straight-forward process, particularly if you're dealing with arrays of primitive types, which suits a large number of computational and statistical tasks. More infromation can be found in R help files, and in the manual for Writing R Extensions. For those who wish to conveniently have their code as an R library, and especially those who want to share their work, it is recommended to eventually package such work up as an R library. DisclaimerAcadia University and the author claim no responsibility for anything resulting from the use or misuse of information presented here. Read and use at your own risk. |