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:
- 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()
) - 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ề - 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.)
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. –
@ 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
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. –