因为个人对Rcpp完全没有兴趣,所以用纯Cpp写,其实你想要做的是这个,多写很废话的代码(头文件是R.h, Rinternals.h):
//cos410250.cpp
#include<R.h>
#include <Rinternals.h>
extern "C" {
void swap1(SEXP a,SEXP b){
int temp;
int *ax=INTEGER(a),*bx=INTEGER(b);
temp=ax[0];
ax[0]=bx[0];
bx[0]=temp;
}
}
R 调用的时候需要讲究一点,专门找了个Win的版本:
dyn.load("cos410250.dll")
SwapTest <- function(a,b,env= .GlobalEnv){
cat("Infunction Before:\t",a,", ",b,'\n')
storage.mode(a) <- storage.mode(b) <- "integer"
.Call("swap1",a,b)
cat("In function After:\t",a,", ",b,'\n')
assign("a", a, envir = env)
assign("b", b, envir = env)
}
a=100L
b=200L
cat("Before:\t",a,", ",b,'\n')
SwapTest(a,b)
cat("After:\t",a,", ",b,'\n')
于是其实问题在于作用域。
下面使用index操作而非S expression
#include<R.h>
#include <Rinternals.h>
extern "C" {
void swap1(SEXP a,SEXP b){
int temp;
int *ax=INTEGER(a),*bx=INTEGER(b);
temp=ax[0];
ax[0]=bx[0];
bx[0]=temp;
}
void swap2(int *ax,int* bx){
int temp;
temp=ax[0];
ax[0]=bx[0];
bx[0]=temp;
Rprintf("In C value:[%d, %d]\n",ax[0],bx[0]);
}
}
以及相应的R代码
#
dyn.load("cos410250.dll")
SwapTest <- function(a,b,env= .GlobalEnv){
cat("Infunction Before:\t",a,", ",b,'\n')
storage.mode(a) <- storage.mode(b) <- "integer"
.Call("swap1",a,b)
cat("In function After:\t",a,", ",b,'\n')
assign("a", a, envir = env)
assign("b", b, envir = env)
}
SwapTest2 <- function(a,b,env= .GlobalEnv){
cat("Infunction Before:\t",a,", ",b,'\n')
storage.mode(a) <- storage.mode(b) <- "integer"
.C("swap2",a,b)
cat("In function After:\t",a,", ",b,'\n')
assign("a", a, envir = env)
assign("b", b, envir = env)
}
SwapTest3 <- function(a,b,env= .GlobalEnv){
cat("Infunction Before:\t",a,", ",b,'\n')
storage.mode(a) <- storage.mode(b) <- "integer"
re = .C("swap2",a,b)
a=re[[1]]
b=re[[2]]
assign("a", a, envir = env)
assign("b", b, envir = env)
cat("In function After:\t",a,", ",b,'\n')
}
a=100L
b=200L
cat("-------------------------------------------\n")
cat("Use SEXP\n")
cat("-------------------------------------------\n")
cat("Before:\t",a,", ",b,'\n')
SwapTest(a,b)
cat("After:\t",a,", ",b,'\n')
a=100L
b=200L
cat("-------------------------------------------\n")
cat("Use index example 1: Wrong\n")
cat("-------------------------------------------\n")
cat("Another Version:\n")
cat("Before:\t",a,", ",b,'\n')
SwapTest2(a,b)
cat("After:\t",a,", ",b,'\n')
cat("-------------------------------------------\n")
a=100L
b=200L
cat("Use index example 1: Right\n")
cat("-------------------------------------------\n")
cat("The 3rd Version:\n")
cat("Before:\t",a,", ",b,'\n')
SwapTest3(a,b)
cat("After:\t",a,", ",b,'\n')
cat("-------------------------------------------\n")