www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Using out qualifier instead of *, how to pass null?

reply Rick Mann <rmann-d-lang latencyzero.com> writes:
In wrapping this C API, I've been going back and forth between converting
"Foo*" output parameters to "out Foo". I prefer the latter, as I don't have to
take the address at the call site, but I don't seem to be able to pass null
(which the API allows, meaning, "I'm not interested in this return value").

Am I just stuck with Foo*? Alternatively, I can overload the C function with D
wrappers, I suppose. Hmm. That's probably best.
Feb 01 2007
next sibling parent reply Kirk McDonald <kirklin.mcdonald gmail.com> writes:
Rick Mann wrote:
 In wrapping this C API, I've been going back and forth between converting
"Foo*" output parameters to "out Foo". I prefer the latter, as I don't have to
take the address at the call site, but I don't seem to be able to pass null
(which the API allows, meaning, "I'm not interested in this return value").
 
 Am I just stuck with Foo*? Alternatively, I can overload the C function with D
wrappers, I suppose. Hmm. That's probably best.

You can't pass it null, for the same reason that you can't pass null to a C++ function with a reference parameter. I would recommend binding the C API as closely as you can, and then using D's features in a wrapper around it. Generally speaking, this will be the most robust and portable approach. It will give you the convenient D version for most uses, and the raw C version when you need that. -- Kirk McDonald Pyd: Wrapping Python with D http://pyd.dsource.org
Feb 01 2007
parent =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Kirk McDonald wrote:

 I would recommend binding the C API as closely as you can, and then 
 using D's features in a wrapper around it. Generally speaking, this will 
 be the most robust and portable approach. It will give you the 
 convenient D version for most uses, and the raw C version when you need 
 that.

Having just rewritten parts of wxD, I second recommending that approach. (for wxWidgets it had to be done anyway, because it's a C++ API library, but generally speaking it is easier to keep each language to its own...) This normally also includes offering legacy aliases, for C portability. --anders PS. Rick, for your API wrapper you might find this article interesting: http://www.eclipse.org/articles/Article-SWT-Design-1/SWT-Design-1.html Bonus points are awarded for completing the Mac OS X DWT port to Carbon, that Carlos started on: http://dsource.org/forums/viewtopic.php?t=1169
Feb 01 2007
prev sibling parent reply Derek Parnell <derek psych.ward> writes:
On Thu, 01 Feb 2007 03:00:01 -0500, Rick Mann wrote:

 In wrapping this C API, I've been going back and forth
 between converting "Foo*" output parameters to "out Foo". 
 I prefer the latter, as I don't have to take the address
 at the call site, but I don't seem to be able to pass null
 (which the API allows, meaning, "I'm not interested in
 this return value").
 
 Am I just stuck with Foo*? Alternatively, I can overload
 the C function with D wrappers, I suppose. Hmm. That's
 probably best.

Is not possible to use a 'null' object ... ? class Foo {} void Bar(out Foo f) { if (f is null) ... else ... } Foo NullFoo; Foo RealFoo = new Foo; Bar(NullFoo); Bar(RealFoo); -- Derek Parnell
Feb 01 2007
next sibling parent =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Derek Parnell wrote:

Am I just stuck with Foo*? Alternatively, I can overload
the C function with D wrappers, I suppose. Hmm. That's
probably best.

Is not possible to use a 'null' object ... ?

Probably not to extern C, without a D wrapper ? --anders
Feb 01 2007
prev sibling parent reply xs0 <xs0 xs0.com> writes:
Derek Parnell wrote:
 On Thu, 01 Feb 2007 03:00:01 -0500, Rick Mann wrote:
 
 In wrapping this C API, I've been going back and forth
 between converting "Foo*" output parameters to "out Foo". 
 I prefer the latter, as I don't have to take the address
 at the call site, but I don't seem to be able to pass null
 (which the API allows, meaning, "I'm not interested in
 this return value").

 Am I just stuck with Foo*? Alternatively, I can overload
 the C function with D wrappers, I suppose. Hmm. That's
 probably best.

Is not possible to use a 'null' object ... ? class Foo {} void Bar(out Foo f) { if (f is null) ... else ... } Foo NullFoo; Foo RealFoo = new Foo; Bar(NullFoo); Bar(RealFoo);

hmm.. doesn't out cause (f is null) to be always true in that code? xs0
Feb 01 2007
parent Derek Parnell <derek nomail.afraid.org> writes:
On Fri, 02 Feb 2007 00:38:30 +0100, xs0 wrote:

 Derek Parnell wrote:
 On Thu, 01 Feb 2007 03:00:01 -0500, Rick Mann wrote:
 
 In wrapping this C API, I've been going back and forth
 between converting "Foo*" output parameters to "out Foo". 
 I prefer the latter, as I don't have to take the address
 at the call site, but I don't seem to be able to pass null
 (which the API allows, meaning, "I'm not interested in
 this return value").

 Am I just stuck with Foo*? Alternatively, I can overload
 the C function with D wrappers, I suppose. Hmm. That's
 probably best.

Is not possible to use a 'null' object ... ? class Foo {} void Bar(out Foo f) { if (f is null) ... else ... } Foo NullFoo; Foo RealFoo = new Foo; Bar(NullFoo); Bar(RealFoo);

hmm.. doesn't out cause (f is null) to be always true in that code?

LOL... yes it does. I was concentrating on the problem - "I don't seem to be able to pass null", but missed that obvious gotcha. This code below actually works though... // ------------ import std.stdio; class Foo { char[] m_id; this(char[] x) { m_id = x.dup; } } void Bar(inout Foo f) { if (f is null) writefln("NULL"); else writefln("Got %s", f.m_id); } void main() { Foo NullFoo; Foo FooA = new Foo("Fred"); Foo FooB = new Foo("Betty"); Bar(NullFoo); Bar(FooB); Bar(FooA); } // ------------ -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocrity!" 2/02/2007 11:04:56 AM
Feb 01 2007