Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upRewrite all the bindings in a better way #85
Conversation
All the FFI functions have fancy types now and use references instead of raw pointers for arguments. Now, a CFRef<T> value represents a refcounted value to be released on Drop, CFShared<T> represents a shared value that can be retained to produce a new CFRef<T> (this will be a useful distinction for mutable types, where a bare T shouldn't be retainable to keep unique ownership). To simplify things and avoid either having wrappers of wrappers of all methods behind traits, I put the safe and thin methods directly on the opaque FFI types. Let's begin the infinite bikeshedding!
|
As I believe you are aware, I am very opposed to putting this much logic in a -sys package. It breaks with the convention of literally every -sys crate I am aware of. That convention is there because it allows -sys crates to be "dumb" reflections of the API they bind to, and allow people to make whatever abstractions they want to on top of that. In particular, since core-foundation-sys declares in its Cargo.toml that it links to The fact that it simplifies things for the implementation of core-foundation is not really an excuse IMO. I tend to care far more about the convenience of downstream users of the libraries I work on than my own. |
And that's why the
If we are on the topic of conventions, are you aware that
Yes, I agree with you. But the convenience of downstream users with my new bindings still greatly improve, because they don't need to have to use traits, and they still see only one type, and they don't have an additional level of indirection, and they don't need to retain every single value retrieved with "the get rule" like in the current bindings. |
Why isn't it supposed to?
I don't see why any of that is incompatible with leaving the bindings unchanged and overhauling the core-foundation crate? |
Oh right. I can't read. What's the problem though since you have the FFI functions? Just don't use the impls. I don't understand your point about not being able to coexist with other things or whatever.
Needing at least 3 or 4 types per binding, compared to 1 per binding and |
|
Is it even a problem if 2 crates link to the same framework through |
|
It is I believe undefined behavior to bind the same extern fn with multiple different signatures. In addition, though it doesn't apply here since Core Foundation is a system library, you don't want to end up with two copies of a library with e.g. two crates dynamically linking to different versions of the same library, or pulling in 2 statically linked versions, etc. |
Again, I really don't understand why the definitions need to be in the -sys crate to pull off a CFRef setup. |
eddyb
commented
Sep 30, 2016
|
@sfackler FWIW, |
|
How can other downstream users who don't necessarily want to use all of the other stuff in the -sys crate use this as an FFI crate if the FFI definitions depend on that stuff e.g. pub fn CFAllocatorGetDefault() -> Option<&'static CFShared<CFAllocator>>; |
|
Just store a pointer to Note that this is all mostly a theoretical problem, given there are only 2 crates that depends on |
|
I am the owner of one of those 2 crates and I am telling you that the changes to the -sys side is a significant step backwards. |
|
I'm quite sad to focus on a theoretical problem that seems to come down to "but my |
|
You didn't explain how it is a significant step backwards except that it goes against a convention that we can very much evolve, without even trying to use the code. This feels like a gut reaction more than anything else. |
|
I will write up my thoughts when I have a chance (might not have a chance until tomorrow, sorry). |
|
Thanks! No problem I can wait. :)
|
|
@sfackler I am going to make a PR on |
This type provides DerefMut access to the underlying Core Foundation type. Will be used for CFMutableString and friends.
|
@sfackler Ping? |
|
Ah yes, sorry. So, here is a basic breakdown of my thoughts:
|
|
Here's an example of some stuff in OpenSSL that I think is somewhat similar to this, and how it's pretty painless do do without needing to modify the FFI definitions directly: sfackler/rust-openssl@0f4a22f. Nothing more than some |
I wouldn't trust a tool doing this, everything must be checked by a human because C and Rust don't match. And if you check it, you can do it yourself and use better types. I can understand that you dislike custom types in FFI, but what is wrong with
Wrong, I had to check the source code of CF many times to even be sure what were the exact semantics with regard to retained arguments.
You can't abuse the amount of safety, that's the point: For example, you can't retain a bare
Do you mean you want to experiment with my branch and do the separation again on top of it? That would be cool, I'm willing to see if that ends up with better code. |
These tools exist for a reason. libc had several things mis-bound until it added CI-time checks against the raw C headers, and the same was true when we added those checks to rust-openssl. |
|
But CF headers don't say anything against get/create rules etc. Some things I had to check directly in the source code of CF. |
|
I know, just like I have to source dive into openssl on top of having automated checks of FFI bindings. |
|
Fair enough, I'll think about how to preserve the split. Meanwhile, did you have the time to look at the higher-level stuff I wrote? |
|
|
ghost
commented
Jan 2, 2017
|
@nox I took a look at the higher level stuff, and I think it is a lot nicer than the current API in many ways. Have you thought about how we can get this working with the |
|
For what it's worth, I concur with @sfackler that |
|
FWIW I'm willing to rewrite it this way only because the community asks so, but I still believe I'm right that this is a bad idea, given it leads to way more code. Time will tell who was right. |
|
@nox do you mind giving an overview of what your approach here is going to be? |
|
I firmly believe that blocking this PR set back the whole core-* ecosystem by far because no one else is willing to clean up all our bindings. I should have just went ahead with my original proposal. I still don't agree with @sfackler that the bindings should be as dumb as possible, because dumb code is a bad idea. |
|
No need to keep this PR open though. |
Font smooth <!-- Reviewable:start --> This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/core-graphics-rs/85) <!-- Reviewable:end -->
Make CTFontDescriptor::font_path() return filesystem path, not URL Prior to this commit, the return string was in the format `file:///foo/bar.otf`. We now omit the leading `file://` portion. This also properly retains characters that are not URL safe. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/core-text-rs/85) <!-- Reviewable:end -->
nox commentedSep 30, 2016
•
edited by larsbergstrom
All the FFI functions have fancy types now and use references instead of raw pointers for arguments.
Now, a
CFRef<T>value represents a refcounted value to be released onDrop,CFShared<T>represents a shared value that can be retained to produce a newCFRef<T>(this will be a useful distinction for mutable types, where a bareTshouldn't be retainable to keep unique ownership).To simplify things and avoid either having wrappers of wrappers of all methods behind traits, I put the safe and thin methods directly on the opaque FFI types.
Let's begin the infinite bikeshedding!
This change is