@hadley: rất tiếc, tôi không có tài nguyên cụ thể để giúp bạn bắt đầu với C ++. Tôi đã chọn nó từ sách của Scott Meyers (C ++ hiệu quả, C ++ hiệu quả hơn, v.v.) nhưng đây không thực sự là những gì người ta có thể gọi là giới thiệu.
Chúng tôi hầu như chỉ sử dụng giao diện .Call để gọi mã C ++. Quy tắc đủ dễ dàng:
- Hàm C ++ phải trả về một đối tượng R. Tất cả các đối tượng R đều là SEXP.
- Hàm C ++ lấy từ 0 đến 65 đối tượng R làm đầu vào (lại là SEXP)
- nó phải (không thực sự, nhưng chúng ta có thể tiết kiệm này cho sau này) được khai báo với C liên kết, hoặc với extern "C" hoặc RcppExport bí danh mà định nghĩa Rcpp.
Vì vậy, một hàm .Call được khai báo như thế này trong một số tệp tiêu đề:
#include <Rcpp.h>
RcppExport SEXP foo( SEXP x1, SEXP x2 ) ;
và được triển khai như thế này trong tệp .cpp:
SEXP foo( SEXP x1, SEXP x2 ){
...
}
Không còn nhiều điều cần biết về R API để sử dụng Rcpp.
Hầu hết mọi người chỉ muốn xử lý các vectơ số trong Rcpp. Bạn làm điều này với lớp NumericVector. Có một số cách để tạo một vectơ số:
Từ một đối tượng hiện có mà bạn chuyển xuống từ R:
SEXP foo( SEXP x_) {
Rcpp::NumericVector x( x_ ) ;
...
}
Với các giá trị đã cho bằng cách sử dụng hàm :: create static:
Rcpp::NumericVector x = Rcpp::NumericVector::create( 1.0, 2.0, 3.0 ) ;
Rcpp::NumericVector x = Rcpp::NumericVector::create(
_["a"] = 1.0,
_["b"] = 2.0,
_["c"] = 3
) ;
Có kích thước nhất định:
Rcpp::NumericVector x( 10 ) ; // filled with 0.0
Rcpp::NumericVector x( 10, 2.0 ) ; // filled with 2.0
Sau đó, khi bạn có một vector, điều hữu ích nhất là trích xuất một phần tử từ nó. Điều này được thực hiện với toán tử [], với lập chỉ mục dựa trên 0, vì vậy, ví dụ tính tổng các giá trị của một vectơ số sẽ giống như sau:
SEXP sum( SEXP x_ ){
Rcpp::NumericVector x(x_) ;
double res = 0.0 ;
for( int i=0; i<x.size(), i++){
res += x[i] ;
}
return Rcpp::wrap( res ) ;
}
Nhưng với đường Rcpp, giờ đây chúng ta có thể làm điều này độc đáo hơn nhiều:
using namespace Rcpp ;
SEXP sum( SEXP x_ ){
NumericVector x(x_) ;
double res = sum( x ) ;
return wrap( res ) ;
}
Như tôi đã nói trước đây, tất cả phụ thuộc vào loại mã bạn muốn viết. Xem xét những gì mọi người làm trong các gói dựa trên Rcpp, kiểm tra các lần tải trang, kiểm tra đơn vị, quay lại với chúng tôi trong danh sách gửi thư. Chúng tôi luôn sẵn lòng giúp đỡ.