2013-07-08 3 views
5

私は初めて.Callを使っています。.Callを使ってCからRまでLanugageから整数ベクトルを得る

#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; 
} 

。したがって、私は呼び出しR CMD SHLIB DLL(ここで問題ない)を作成: 私は整数を渡し、(Rに対して)SEXPを返す以下の簡単なコードを書きました。

(Rで)以下のコードを実行すると、私は(100,0,0,0,0)Cより答え異なるを得る:

> 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:たぶん私は値を取得していますその値の代わりにポインタ変数 "a"のアドレスの値を返します。しかし、私はここで何が欠けているのか分からない。

EDIT:@JoshuaUlrichの答えを使用して

私は、コードを固定し、より多くの機能を追加しました。 固定コードは次のとおりです。

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; 
} 

Rからの呼び出しあなたが得る:

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 

答えて

1

あなたsetInt関数定義は、唯一の引数としてC int型を受け入れます。しかし、あなたのRコードでは、CのintではなくINTSXPを渡しています。一般に、.Call経由で呼び出されるC関数は、引数としてSEXPのみを受け入れる必要があります。また、あなたはおそらくaINTSXPlength(a)==1であることを確認する必要があることに注意してください

SEXP setInt(SEXP 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] = AS_INTEGER(a); 

    UNPROTECT(1); 
    return myint; 
} 

だからにあなたの関数の定義を変更してください。 length(a) > 1の場合は、これを行うことができます:

int *p_a; 
p_a = INTEGER_POINTER(a); 
p_myint[0] = p_a[1]; // get second element from a 
+0

ありがとうございます@JoshuaUlrich、他にもう1つ質問してください。 'a'が整数のベクトルで、例えば[2]の値を返すとすればどうすればよいでしょうか。 – MSardelich

+0

もう一度ありがとうございました...ここに私のループを閉じます... – MSardelich

関連する問題