## Consider the following C function, which is included
## in the dotCall64 package:
## void get_c(double *input, int *index, double *output) {
## output[0] = input[index[0] - 1];
## }
##
## We can use .C64() to call get_c() from R:
.C64("get_c", SIGNATURE = c("double", "integer", "double"),
input = 1:10, index = 9, output = double(1))$output
if (FALSE) {
## 'input' can be a long vector
x_long <- double(2^31) ## requires 16 GB RAM
x_long[9] <- 9; x_long[2^31] <- -1
.C64("get_c", SIGNATURE = c("double", "integer", "double"),
input = x_long, index = 9, output = double(1))$output
## Since 'index' is of type 'signed int' (a 32-bit integer),
## it can only address the first 2^31-1 elements of 'input'.
## To also address elements beyond 2^31-1, we change the
## definition of the C function as follows:
## #include // for int64_t
## void get64_c(double *input, int64_t *index, double *output) {
## output[0] = input[index[0] - 1];
## }
## Now, we can use .C64() to call get64_c() from R.
.C64("get64_c", SIGNATURE = c("double", "int64", "double"),
input = x_long, index = 2^31, output = double(1))$output
## Note that 2^31 is of type double and .C64() casts it into an
## int64_t type before calling the C function get64_c().
## The performance of the previous call can be improved by
## setting additional arguments:
.C64("get64_c", SIGNATURE = c("double", "int64", "double"),
x = x_long, i = 2^31, r = numeric_dc(1), INTENT = c("r", "r", "w"),
NAOK = TRUE, PACKAGE = "dotCall64", VERBOSE = 0)$r
## Consider the same function defined in Fortran:
## subroutine get64_f(input, index, output)
## double precision :: input(*), output(*)
## integer (kind = 8) :: index ! specific to GFortran
## output(1) = input(index)
## end
## The function is provided in dotCall64 and can be called with
.C64("get64_f", SIGNATURE = c("double", "int64", "double"),
input = x_long, index = 2^31, output = double(1))$output
}
Run the code above in your browser using DataLab