external_ptr issues
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 5/5
- Thời gian dự kiến
- Hơn một tuần
- Mức phù hợp với người mới
- 25/100
Hướng nghiên cứu
Start by reviewing the existing external_pointer implementation and the attached safe_external_ptr.txt example, then read the discussion about type tags, protected data, and copy and move semantics. Done would require a decided scope for improving external_pointer or adding an alternative wrapper, with its intended semantics documented and validated.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
In a recent project I had some issues with external_pointer that I wanted to discuss. First, a bit of context: My goal was to make a simple C++ library consisting of a bunch of classes that do stochastic simulations accessible from R. My approach was pretty straight-forward -- for every class T I created a C++ function that calls the constructor returns an external_pointer<T>, and for every member function I created a cpp11 function that takes an external_pointer<T> as its first argument.
The issues I faced were the following:
-
No type safety. On the R side, there is no distinction between
external_pointer<T>andexternal_pointer<U>, so passing the wrong type of object to a cpp11 function is possible and will lead to crashes. -
No support for protected data attached to the external pointer. This is relevant for C++ classes that keep references to instances of other wrapped classes around. For these references to stay valid, the referenced objects must live at least until the external pointer owning the referencing object is destructed. This is exactly what external pointers guarantee for the protected data SEXP they support, but the current
external_pointerimplementation does not make this functionality accessible. -
While the semantics of R's external pointer are clear to me (I think), I didn't quite understand the semantics of cpp11's
external_pointerclass. I would have expected the class to have essentially the same semantics assexpfor copies and moves, i.e. basically those just copy the underlying SEXP around, but take care to protect it from garbage collection. However, it seems thatexternal_pointerinstead considers itself to own a particular external pointer SEXP, and copies it (using Rf_shallow_copy) whenexternal_pointeris copied. What is the rational there? -
Probably due to (3) my attempts at wrapping a class whose instances keep references to other objects around lead to crashes. Basically, what I did was to let the external_pointer point not to the class directly, but to a holder struct that contains external_pointer instances for the object plus all the objects it references. Whether the problem was my code or
external_pointerI couldn't tell because I didn't really understand the intended proper usage of external_pointer in this case.
I ended up creating my own external pointer class, safe_external_pointer (code is attached). I used external_pointer as a template, but changed the following things
-
The tag mechanism of R's external pointers is used to provide rudimentary type safety.
-
The protected data mechanism is exposed to the user
-
The underlying external pointer SEXP is considered to be immutable, i.e. never changed after its creation. The copy and move semantics of
safe_external_pointerare the same as that ofsexp. Thus,safe_external_pointerdoes not really "own" the underlying external pointer SEXP, but rather is one of many references to it.
For my use case, this simplified things a lot, and it got rid of the crashes I wasn't able to debug before. Whether other use-cases would be made more complicated by these changes (in particular (3)), I don't know of course. Still, I figured I'd share my code and see if there's any interest in either including parts of it into cpp11's external_pointer, or including it as an alternative external pointer wrapper alongside the existing one.
safe_external_ptr.txt
- Ngôn ngữ chính
- C++
- Star
- 224
- Fork
- 52
- Chỉ số merge pull request
- Không có pull request nào được merge trong 30 ngày
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của r-lib/cpp11
-
Dimension error with `r_vector` Đang mở
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 35/100
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 48/100
-
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 20/100
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 42/100
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 45/100
Issue tương tự
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 90/100
AXERA-TECH/ax-llm#77 ·
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 90/100
games-on-whales/wolf#509 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 74/100
-
bug-unconfirmed
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100