2012-06-15 24 views
11

Có một số rắc rối với bộ sưu tập rác của R, khi truyền các đối tượng tới C++.làm thế nào để ức chế R thu gom rác khi chuyển các đối tượng đến C/C++?

Chúng tôi có các tình huống sau:

  1. chúng ta tạo ra một chức năng ẩn danh trong R, và vượt qua nó để C++ (thông qua .Call())
  2. cáC++ mã C lưu trữ các đối tượng chức năng R để sử dụng sau (như một loại SEXP) và trả về
  3. sau này, một số khác C++ gọi nói R chức năng đối tượng sử dụng R_tryEval()

giữa bước 2 và 3, đối tượng hàm R xuất hiện để lấy rác do R. Điều này dẫn đến sự cố vì R_tryEval() cố gắng thực hiện một cái gì đó không còn đại diện cho đối tượng hàm R hợp lệ nữa. Đó là công bằng, như chúng ta đã không thực hiện bất cứ điều gì để nói với R rằng đối tượng chức năng vẫn đang được sử dụng ...

Với ý nghĩ đó:

  • là có một cách, từ ++ mã C, để đánh dấu đối tượng chức năng R như đang được sử dụng (chẳng hạn như nó không nhận được gc'd)?
  • hoặc có cách nào an toàn để sao chép đối tượng hàm R, trong mã C++ và tự định đoạt nó sau khi chúng tôi gọi R_tryEval()?

(Theo như tôi hiểu, các macro PROTECT()/UNPROTECT() không phải là một tùy chọn ở đây vì những có nghĩa vụ phải cân bằng trong phạm vi tương tự. Như trong, chúng ta không thể gọi PROTECT() khi hàm được truyền đầu tiên C++ và sau đó gọi UNPROTECT() sau khi nó đã được thực hiện.)

+0

Bạn 'lưu trữ' đối tượng như thế nào? Tôi nghĩ rằng (mà không thực sự suy nghĩ) bạn có thể sử dụng một con trỏ bên ngoài. Nếu không, bạn có thể chỉ đơn giản là giữ nó sống ở R một nơi nào đó và sử dụng findVar để gọi lại khi cần thiết. –

+0

@ Jeff - cảm ơn. Những gì bạn đã mô tả là rất gần với cách giải quyết mà chúng tôi nghĩ ra: thêm các đối tượng hàm vào một danh sách, ở phía R, trước khi chuyển chúng sang C++. (Chúng tôi vui mừng tiếp tục làm điều này, nhân tiện ... chỉ muốn đảm bảo không có chức năng "chính thức" mà chúng tôi phải gọi để gắn cờ đối tượng là không-gc.) – qethanm

+1

Theo như hack đi, cái này có thể lấy bánh. Xem câu trả lời của Martin cho một giải pháp thích hợp ngay cả khi bạn không sử dụng Rcpp. –

Trả lời

3

tôi nghĩ rằng bạn đang tìm kiếm

/* preserve objects across GCs */ 
void R_PreserveObject(SEXP); 
void R_ReleaseObject(SEXP); 

trong tiêu đề R_internals.h.

+0

... và nếu bạn sử dụng Rcpp, điều này sẽ được áp dụng tự động cho các đối tượng của bạn. –

+0

Rất cám ơn - đây chỉ là những gì tôi đã làm sau. Trường hợp đóng cửa. – qethanm

Các vấn đề liên quan