Tôi đang sử dụng .Call lần đầu tiên. Tôi đã viết code đơn giản dưới đây, nơi tôi vượt qua một số nguyên và trả về một sexp (R):Lấy một số nguyên từ C sang R Lanugage bằng cách sử dụng .Call
#include <R.h>
#include <Rdefines.h>
SEXP setInt(int *a) {
SEXP myint;
int *p_myint;
int len = 5;
PROTECT(myint = NEW_INTEGER(len)); // Allocating storage space
p_myint = INTEGER_POINTER(myint); // ponit to SEXP object
p_myint[0] = *a;
UNPROTECT(1);
return myint;
}
Vì vậy, tôi gọi R CMD SHLIB mà tạo ra dll (không có vấn đề ở đây).
Khi chạy đoạn code dưới đây (R), tôi nhận được một câu trả lời khác nhau hơn c (100,0,0,0,0):
> dyn.load(file.path(path.dll,paste0("useC", .Platform$dynlib.ext)))
> a<-100
> out<- .Call("setInt",as.integer(a))
> out
[1] 536870925 0 0 0 0
PS: Có lẽ tôi đang nhận được giá trị của địa chỉ của biến con trỏ "a", thay vì giá trị của nó. Nhưng tôi không biết những gì tôi đang thiếu ở đây.
EDIT:
Sử dụng câu trả lời của tôi @JoshuaUlrich cố định mã và thêm nhiều tính năng hơn. Mã cố định là:
SEXP setInt(SEXP a,SEXP pos) {
SEXP myint;
int *p_a;
int *p_myint;
int len = 5;
PROTECT(myint = NEW_INTEGER(len)); // Allocate storage space, with default 5 zeroes
p_myint = INTEGER_POINTER(myint); // ponit to SEXP object
p_a = INTEGER_POINTER(a);
p_myint[0] = p_a[(asInteger(pos)-1)]; // get the element at pos
UNPROTECT(1);
return myint;
}
Khi gọi từ R bạn nhận được:
a<-c(100,200,300)
pos<-1
out<- .Call("setInt",as.integer(a),as.integer(pos))
> out
[1] 100 0 0 0 0
pos<-2
out<- .Call("setInt",as.integer(a),as.integer(pos))
> out
[1] 200 0 0 0 0
Cảm ơn rất nhiều @JoshuaUlrich, chỉ một câu hỏi nữa. Tôi nên làm gì nếu 'a' là một vectơ các số nguyên và tôi sẽ trả về giá trị của [2] chẳng hạn. – MSardelich
cảm ơn rất nhiều lần ... nó đóng các vòng của tôi ở đây ... – MSardelich