-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Ability to create an opaque type with methods #4638
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I have no experience with wrapping C APIs, but if I understand you correctly, a variant of distinct types (#1595) might work really well for something like this. If There is some overlap between this and the #1170 proposal, but here there wouldn't be the same ambiguity to which namespace a method belongs to. // distinct type with (optional) namespace attached
const A = distinct(TypeToWrap){ // TypeToWrap can be a primitive, container or opaque type
fn methodOn_TypeToWrap(self: @This()) void{
// ...
}
};
const a : A = @as(A,TypeToWrap.init());
a.methodOn_TypeToWrap(); // unified call syntax routed to namespace of distinct type A
a.origMethod(); // syntax error. use `TypeToWrap.origMethod(a)` instead
// no namespace attached. Unified syntax calls routed to TypeToWrap
const B = distinct(TypeToWrap); The original intent of distinct types would of course apply, with the compiler being able to helpfully differentiate between types that at runtime are indistinguishable. |
I've been working on some idiomatic libwayland bindings recently and being able to define methods for opaque types would make the bindings both easier to write and more ergonomic to use. Currently my pattern looks like this: const Display = struct {
const Impl = @Type(.Opaque);
impl: *Impl,
extern fn wl_display_get_fd(display: *Impl) c_int;
pub fn getFd(display: Display) os.fd_t {
return wl_display_get_fd(display.impl);
}
}; For this basic use case, wrapping the opaque pointer in a struct works alright, but for more complex use-cases such as registering callbacks it quickly becomes unwieldy. The user of libwayland is asked to supply a function with the following signature: fn (data: ?*c_void, display: *Display.Impl, id: u32) callconv(.C) void To provide a nice api and "hide" the fact that the As for how best to expose this feature on a language level, I propose adding an const Display = opaque {
extern fn wl_display_get_fd(display: *Display) c_int;
pub fn getFd(display: *Display) os.fd_t {
return wl_display_get_fd(display);
}
}; I think this would be better than |
Dupe of #5574 |
I'm manually wrapping a C API which has opaque types. I'd like to be able to add methods to the opaque type rather than using free functions or wrapping it in a struct.
Wrapping a pointer in a struct has issues when it comes to identity:
getPointer() == myThing
is no longer true (instead the user needs to do something like:getPointer() == myThing.real_ptr
)The text was updated successfully, but these errors were encountered: