runC: Run a C function based on C interface from R

View source: R/runC.R

runCR Documentation

Run a C function based on C interface from R

Description

This function is a wrapper function to help users run C functions using '.C' and '.Call' interface without taking care of dynamic links.

Usage

runC(
  RCall = {
     .C("C_dist", x1, x2, nchannel, ncells, nnodes, xdist = 0)$xdist
 },
  cfile = "src/testC.c",
  body = character(),
  includes = character(),
  ignoreBuildMessage = TRUE,
  rebuild = TRUE,
  unload = TRUE
)

Arguments

RCall

The R script to use either '.C' or '.Call' to call the C function(s) that is/are defined in 'cfile' or 'body'. Please note RCall is not a string, it is a standard R script, and it can only be put here, but cannot be assigned to a variable outside of the 'runC' function. If you have multiple lines of R script here, then put the curly brackets '' arround them.

cfile

a C code file where the C function that is called in 'RCall' parameter is declared and defined.

body

The C code that are stored as a character/string (vector). By default, it's an empty character. But if this parameter is provided with a non-empty character, the text in 'includes' and 'body' will be written into a temporary file ('tempfile()'), which, instead of 'cfile', will be compiled and loaded in R. Please note that, the '\n' in the source C code needs to be escaped as '\\n', and '\t' as '\\t', '\\' as '\\\\', etc.

includes

This includes "#include <...>" C codes ahead of 'body'. Default is character().

ignoreBuildMessage

logical, whether to ignore the compiling message during build, default is TRUE.

rebuild

logical, whether to compile and rebuild the dynamic link file, default is TRUE.

unload

logical, whether to unload the dynamic link file after finished, default is TRUE.

Value

It returns what '.cCall' would return.

Examples

## Not run: 
## Suppose you have a C file called `directory/file.c`, in which you have 
## defined a C function called `void myCfun(int *x)`.
## then you can call this function from R like this:
x = 1:5
run(RCall = {y = .C("myCfun", xname = x)$xname}, cfile = "directory/file.c")
# Here, x is processed by the C function `myCfun` and assigned to y.
# Because `.C` is used here, `myCfun` does not return anything to R, but `.C` function 
# returns all of the parameters (with/without modifications) that you passed to `myCfun` 
# as a list, either named or unnamed depending on whether you assign it a 
# name (here xname) in `.C` function.


## Alternatively, you can pass C code to `body` and `includes` parameters.
## Suppose you have a piece of C code (not a C file) as follow
'
#include<stdio.h>
void myCfun(int *x){
  printf("The first number of Your input is %d, ", x[0]);
  int y = 100;
  *x = y;
  printf("Your first number is changed to %d\n", x[0]);
}
'
## Then you can assign it to `body` in runC, but remember to escape `\n` in the C code.
ccode = '
#include<stdio.h>
void myCfun(int *x){
  printf("The first number of Your input is %d, ", x[0]);
  int y = 100;
  *x = y;
  printf("Your first number is changed to %d\\n", x[0]); // escape the backslash
}
'
## And then you can call `myCfun` as before.
x = 1:5
runC(RCall = {y = .C("myCfun", xname = x)$xname}, body = ccode)
print(y)

## You can also put `#include<stdio.h>` in the `includes` parameter and the rest in `body`.
ccode2 = '
void myCfun(int *x){
  printf("The first number of Your input is %d, ", x[0]);
  int y = 100;
  *x = y;
  printf("Your first number is changed to %d\\n", x[0]); // escape the backslash
}
'
inclu2 = '
#include<stdio.h>
'

## And then you can call `myCfun` as
x = 1:5
runC(RCall = {y = .C("myCfun", xname = x)$xname}, body = ccode2, includes = inclu2)
print(y)


# You can also use `.Call` function to call C functions, here is an example
ccode3 = '
SEXP myCfun(SEXP x){
  x = duplicate(x);
  int *vx = INTEGER(x);
  printf("The first number of Your input is %d, ", vx[0]);
  int y = 100;
  vx[0] = y;
  printf("Your first number is changed to %d\\n", vx[0]); // escape the backslash
  return(x);
}
'

inclu3 = '
#include <R.h>
#include <Rinternals.h>
#include <stdio.h>

'
x = 1:5
runC(RCall = {y = .Call("myCfun", x)}, body = ccode3, includes = inclu3)
print(y)

## End(Not run)

paodan/funcTools documentation built on April 1, 2024, 12:01 a.m.