digitalmars.D.learn - Using a struct as a wrapper for an extern(C) opaque type, no default
- Jeremy DeHaan (12/12) Dec 16 2015 Hi all. I'm interfacing to some C code which include an opaque
- Jakob Ovrum (8/20) Dec 16 2015 Using a factory function alongside @disable this(); is the
- Jeremy DeHaan (8/30) Dec 16 2015 Thanks. I guess what bugs me is that I always try to hide the
- Jakob Ovrum (9/16) Dec 16 2015 I completely understand your sentiment, but I don't see how
- Jakob Ovrum (17/18) Dec 16 2015 Also, I would be wary of lazy initialization. We have bad
- Jeremy DeHaan (9/27) Dec 16 2015 Thanks for the heads up. I'll think more on this, but you made a
- Jakob Ovrum (6/12) Dec 16 2015 If the type you're wrapping would still be accessed through a
Hi all. I'm interfacing to some C code which include an opaque type and some C functions that create and work with a pointer to that type. I want to wrap up everything in a struct, and the only thing that seems to bug me is initialization. Since it is C code, I obviously can't read the function that creates the opaque type. Not only that, I can't define a default constructor. What are my options here? This is for an API that is intended to be used by people other than myself, so I'd like to use something that doesn't look ugly or isn't a hack. I really don't like the idea of using a factory method or overriding opCall. Am I basically out of luck and need to resort to one of these methods?
Dec 16 2015
On Thursday, 17 December 2015 at 03:31:37 UTC, Jeremy DeHaan wrote:Hi all. I'm interfacing to some C code which include an opaque type and some C functions that create and work with a pointer to that type. I want to wrap up everything in a struct, and the only thing that seems to bug me is initialization. Since it is C code, I obviously can't read the function that creates the opaque type. Not only that, I can't define a default constructor. What are my options here? This is for an API that is intended to be used by people other than myself, so I'd like to use something that doesn't look ugly or isn't a hack. I really don't like the idea of using a factory method or overriding opCall. Am I basically out of luck and need to resort to one of these methods?Using a factory function alongside disable this(); is the canonical way to do this. Although, if your struct is a reference type, you can simply allow default construction and have it mean a null reference. Using static opCall here is just a factory function with special syntax, but I think it does more harm than good.
Dec 16 2015
On Thursday, 17 December 2015 at 03:43:58 UTC, Jakob Ovrum wrote:On Thursday, 17 December 2015 at 03:31:37 UTC, Jeremy DeHaan wrote:Thanks. I guess what bugs me is that I always try to hide the fact that the API is a wrapper around C stuff, ie, I want to make people feel as though they're using idiomatic D. Doing something like this makes it feel like less idiomatic D and more like a wrapper. I think I have a solution that I like in my own case though. Right now I'm considering something like this: http://dpaste.com/3FH3W13Hi all. I'm interfacing to some C code which include an opaque type and some C functions that create and work with a pointer to that type. I want to wrap up everything in a struct, and the only thing that seems to bug me is initialization. Since it is C code, I obviously can't read the function that creates the opaque type. Not only that, I can't define a default constructor. What are my options here? This is for an API that is intended to be used by people other than myself, so I'd like to use something that doesn't look ugly or isn't a hack. I really don't like the idea of using a factory method or overriding opCall. Am I basically out of luck and need to resort to one of these methods?Using a factory function alongside disable this(); is the canonical way to do this. Although, if your struct is a reference type, you can simply allow default construction and have it mean a null reference. Using static opCall here is just a factory function with special syntax, but I think it does more harm than good.
Dec 16 2015
On Thursday, 17 December 2015 at 04:05:30 UTC, Jeremy DeHaan wrote:Thanks. I guess what bugs me is that I always try to hide the fact that the API is a wrapper around C stuff, ie, I want to make people feel as though they're using idiomatic D. Doing something like this makes it feel like less idiomatic D and more like a wrapper. I think I have a solution that I like in my own case though. Right now I'm considering something like this: http://dpaste.com/3FH3W13I completely understand your sentiment, but I don't see how default construction factors into it. D libraries that *aren't* wrappers around C libraries have the same restriction and have to make the same interface choices. Or did you mean something else? Your code looks good, but make sure you either disable postblit or implement the postblit operator appropriately. The Rule of Three applies well to D.
Dec 16 2015
On Thursday, 17 December 2015 at 04:05:30 UTC, Jeremy DeHaan wrote:http://dpaste.com/3FH3W13Also, I would be wary of lazy initialization. We have bad experiences with it for AAs and standard containers. A typical example would be: void foo(Wrapper w) { ... w.doTheThing(); ... } void main() { Wrapper w; foo(); w.inspect(); // `w` is still a null reference here }
Dec 16 2015
On Thursday, 17 December 2015 at 04:59:20 UTC, Jakob Ovrum wrote:On Thursday, 17 December 2015 at 04:05:30 UTC, Jeremy DeHaan wrote:Thanks for the heads up. I'll think more on this, but you made a good point here. And I guess what I was talking about before is that using a factory method feels klunky to me. If the things I am wrapping had been written in D they could use default initialization, so it feels wrong to do otherwise. I also just don't really like factory methods. They feel like a workaround that the end user has to deal with. But that's just me.http://dpaste.com/3FH3W13Also, I would be wary of lazy initialization. We have bad experiences with it for AAs and standard containers. A typical example would be: void foo(Wrapper w) { ... w.doTheThing(); ... } void main() { Wrapper w; foo(); w.inspect(); // `w` is still a null reference here }
Dec 16 2015
On Thursday, 17 December 2015 at 06:04:14 UTC, Jeremy DeHaan wrote:And I guess what I was talking about before is that using a factory method feels klunky to me. If the things I am wrapping had been written in D they could use default initialization, so it feels wrong to do otherwise. I also just don't really like factory methods. They feel like a workaround that the end user has to deal with. But that's just me.If the type you're wrapping would still be accessed through a reference type, then that reference type would have exactly the same situation. But yeah, it would allow you to make it a value type.
Dec 16 2015