February 28, 2005
John C wrote:
> One thing I don't like with these ports of the Windows SDK headers is the many aliases for basic types - eg, typedef long LONG, typedef LONG LONG_PTR, typedef LONG_PTR LRESULT. Not only does it look ugly (all those caps screaming off the screen), it's also confusing and misleading in D. It may be fine in C/C++ -- many of these are a hangover from the 16-bit days when WPARAM was an unsigned short (I think) or WORD, so the "W" made sense, but it's an unsigned int now. Even worse, LRESULT is a 32-bit long in C (hence the "L" prefix) but a long is 64 bits in D.

Yes, I'm made to wonder why the Windows API needs so many meaningless type aliases.  My guess is that M$ was trying to come up with a cross-language set of type names.

> There are already plenty of basic types in D to remember, so why add this layer of obfuscation? I also note that the D style guide (http://www.digitalmars.com/d/dstyle.html) discourages the practice; that said, the header translations in Phobos ignore the guideline.

Indeed.  I did mention this briefly (see my reply to Mark T on this thread), but there was no comment.  I'm inclined to agree - we D programmers are comfortable with D type names, so we should use them.  I use D type names rather than these aliases throughout SDWF.

> Which is more readable/understandable?
> 
>     extern (Windows) LRESULT windowCallback(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
> 
> or
> 
>     typedef void* Handle = (void*)0; // a typedef, but a useful one
>     extern (Windows) int windowCallback(Handle handle, uint message, uint param1, int param2)

I think we both agree on this.

> (Another thing: how I wish we could wrap callbacks in delegates without proxy classes.)
<snip top of upside-down reply>

What do you mean by this?

Stewart.

-- 
My e-mail is valid but not my primary mailbox.  Please keep replies on the 'group where everyone may benefit.
February 28, 2005
"Stewart Gordon" <smjg_1998@yahoo.com> wrote in message news:cvvl9a$776$1@digitaldaemon.com...
> John C wrote:
>> One thing I don't like with these ports of the Windows SDK headers is the many aliases for basic types - eg, typedef long LONG, typedef LONG LONG_PTR, typedef LONG_PTR LRESULT. Not only does it look ugly (all those caps screaming off the screen), it's also confusing and misleading in D. It may be fine in C/C++ -- many of these are a hangover from the 16-bit days when WPARAM was an unsigned short (I think) or WORD, so the "W" made sense, but it's an unsigned int now. Even worse, LRESULT is a 32-bit long in C (hence the "L" prefix) but a long is 64 bits in D.
>
> Yes, I'm made to wonder why the Windows API needs so many meaningless type aliases.  My guess is that M$ was trying to come up with a cross-language set of type names.
>
>> There are already plenty of basic types in D to remember, so why add this layer of obfuscation? I also note that the D style guide (http://www.digitalmars.com/d/dstyle.html) discourages the practice; that said, the header translations in Phobos ignore the guideline.
>
> Indeed.  I did mention this briefly (see my reply to Mark T on this thread), but there was no comment.  I'm inclined to agree - we D programmers are comfortable with D type names, so we should use them.  I use D type names rather than these aliases throughout SDWF.
>
>> Which is more readable/understandable?
>>
>>     extern (Windows) LRESULT windowCallback(HWND hWnd, UINT uMsg, WPARAM
>> wParam, LPARAM lParam)
>>
>> or
>>
>>     typedef void* Handle = (void*)0; // a typedef, but a useful one
>>     extern (Windows) int windowCallback(Handle handle, uint message, uint
>> param1, int param2)
>
> I think we both agree on this.
>
>> (Another thing: how I wish we could wrap callbacks in delegates without proxy classes.)
> <snip top of upside-down reply>
>
> What do you mean by this?

Simply that there were some way for function pointers (including those requiring an extern attribute, such as callbacks) and delegates to be used interchangably. The workaround I've adopted is to encapsulate both the callback and the delegate in a template class. I'm not sure it's a good design, since the delegate needs to be static, so perhaps it can be improved upon:

class Callback(R, T1, T2, T3, T4) {

  private alias R delegate(T1, T2, T3, T4) Method;
  private extern (Windows) alias R function(T1, T2, T3, T4) Function;

  public this(Method method) {
    method_ = method;
  }

  public Function opCast() {
    return &callback;
  }

  public static extern (Windows) R callback(T1 arg1, T2 arg2, T3 arg3, T4
arg4) {
    return method_(arg1, arg2, arg3, arg4);
  }

  private static Method method_;

};

alias Callback!(int, Handle, uint, uint, int) WndProc;

class Control {

  void registerClass() {
    WNDCLASS wc;
    wc.lpfnWndProc = (WNDPROC)(new WndProc(&windowProc));
  }

  private int windowProc(Handle handle, uint message, uint param1, int
param2) {
    // Now I have access to the class's non-static members. Hurrah.
    ...
  }
}


February 28, 2005
"John C" <johnch_atms@hotmail.com> wrote in message news:cvvnj1$9ic$1@digitaldaemon.com...
> "Stewart Gordon" <smjg_1998@yahoo.com> wrote in message news:cvvl9a$776$1@digitaldaemon.com...
>> John C wrote:
>>> One thing I don't like with these ports of the Windows SDK headers is the many aliases for basic types - eg, typedef long LONG, typedef LONG LONG_PTR, typedef LONG_PTR LRESULT. Not only does it look ugly (all those caps screaming off the screen), it's also confusing and misleading in D. It may be fine in C/C++ -- many of these are a hangover from the 16-bit days when WPARAM was an unsigned short (I think) or WORD, so the "W" made sense, but it's an unsigned int now. Even worse, LRESULT is a 32-bit long in C (hence the "L" prefix) but a long is 64 bits in D.
>>
>> Yes, I'm made to wonder why the Windows API needs so many meaningless type aliases.  My guess is that M$ was trying to come up with a cross-language set of type names.
>>
>>> There are already plenty of basic types in D to remember, so why add this layer of obfuscation? I also note that the D style guide (http://www.digitalmars.com/d/dstyle.html) discourages the practice; that said, the header translations in Phobos ignore the guideline.
>>
>> Indeed.  I did mention this briefly (see my reply to Mark T on this thread), but there was no comment.  I'm inclined to agree - we D programmers are comfortable with D type names, so we should use them.  I use D type names rather than these aliases throughout SDWF.
>>
>>> Which is more readable/understandable?
>>>
>>>     extern (Windows) LRESULT windowCallback(HWND hWnd, UINT uMsg, WPARAM
>>> wParam, LPARAM lParam)
>>>
>>> or
>>>
>>>     typedef void* Handle = (void*)0; // a typedef, but a useful one
>>>     extern (Windows) int windowCallback(Handle handle, uint message,
>>> uint param1, int param2)
>>
>> I think we both agree on this.
>>
>>> (Another thing: how I wish we could wrap callbacks in delegates without proxy classes.)
>> <snip top of upside-down reply>
>>
>> What do you mean by this?
>
> Simply that there were some way for function pointers (including those requiring an extern attribute, such as callbacks) and delegates to be used interchangably. The workaround I've adopted is to encapsulate both the callback and the delegate in a template class. I'm not sure it's a good design, since the delegate needs to be static, so perhaps it can be improved upon:
>
> class Callback(R, T1, T2, T3, T4) {
>
>  private alias R delegate(T1, T2, T3, T4) Method;
>  private extern (Windows) alias R function(T1, T2, T3, T4) Function;
>
>  public this(Method method) {
>    method_ = method;
>  }
>
>  public Function opCast() {
>    return &callback;
>  }
>
>  public static extern (Windows) R callback(T1 arg1, T2 arg2, T3 arg3, T4
> arg4) {
>    return method_(arg1, arg2, arg3, arg4);
>  }
>
>  private static Method method_;
>
> };
>
> alias Callback!(int, Handle, uint, uint, int) WndProc;
>
> class Control {
>
>  void registerClass() {
>    WNDCLASS wc;
>    wc.lpfnWndProc = (WNDPROC)(new WndProc(&windowProc));
>  }
>
>  private int windowProc(Handle handle, uint message, uint param1, int
> param2) {
>    // Now I have access to the class's non-static members. Hurrah.
>    ...
>  }
> }
>

Talking of templates, I'd love to be able to use an alternative syntax for specifying arguments:

  // C++ version, separates out return type and function arguments
  typedef Callback<int (Handle, uint, uint, int)> WndProc;

  // possible D version, although looks unweildy
  alias Callback!(int (Handle, uint, uint, int)) WndProc;


March 01, 2005
John C wrote:
<snip>
>>> (Another thing: how I wish we could wrap callbacks in delegates without proxy classes.)
>> 
>> <snip top of upside-down reply>
>> 
>> What do you mean by this?
> 
> Simply that there were some way for function pointers (including those requiring an extern attribute, such as callbacks) and delegates to be used interchangably. The workaround I've adopted is to encapsulate both the callback and the delegate in a template class. I'm not sure it's a good design, since the delegate needs to be static, so perhaps it can be improved upon:
<snip>

The problem is that a delegate consists of two pieces of information: the function pointer and the 'this' pointer.  C-based APIs such as the Windows API cannot use delegates, at least directly.  To pass in a delegate where a function pointer is expected would mean losing the 'this' pointer, and consequently the external API cannot call the function.

Your hack would work only if throughout your program, you use only one delegate per function signature as a callback.  But if that's so, there's a simpler hack still: have a global variable referencing the object on which it is called, and define a function that simply calls that method of this object.  This approach also makes it possible to do a small, defined number of delegates with the same signature.

Stewart.

-- 
My e-mail is valid but not my primary mailbox.  Please keep replies on the 'group where everyone may benefit.
March 02, 2005
Hi folks,

As a D newbie, but experience Windows developer, I though these comments may be worth considering...

>> One thing I don't like with these ports of the Windows SDK headers is the many aliases for basic types - eg, typedef long LONG, typedef LONG LONG_PTR, typedef LONG_PTR LRESULT. Not only does it look ugly (all those caps screaming off the screen), it's also confusing and misleading in D. It may be fine in C/C++ -- many of these are a hangover from the 16-bit days when WPARAM was an unsigned short (I think) or WORD, so the "W" made sense, but it's an unsigned int now. Even worse, LRESULT is a 32-bit long in C (hence the "L" prefix) but a long is 64 bits in D.

Here, there is actually a semantic difference. A LONG is a 32-bit value,
easy enough.
LONG_PTR however was introduced with Win64 and varies to be a 32-bit or
64-bit
number depending on platform, basically a LONG that is guaranteed big enough
to hold
a pointer. Allowing for the fact that API styles frequently require you to
pass a pointer as
a LPARAM-type value (also pointer-sized), this makes a lot of sense actually

> Yes, I'm made to wonder why the Windows API needs so many meaningless type aliases.  My guess is that M$ was trying to come up with a cross-language set of type names.

Again, the purpose here is not to be cross-language (these kind of names
never made an
appearance in VB), but to support C compilers where the basic types have
different sizes
(a rare occurence on Windows, but theoretically possible) - all such a
compiler-vendor
would need to do is define a few thousand typedef's appropiately (that was
sarcasm).

>> There are already plenty of basic types in D to remember, so why add this layer of obfuscation? I also note that the D style guide (http://www.digitalmars.com/d/dstyle.html) discourages the practice; that said, the header translations in Phobos ignore the guideline.
>
> Indeed.  I did mention this briefly (see my reply to Mark T on this thread), but there was no comment.  I'm inclined to agree - we D programmers are comfortable with D type names, so we should use them.  I use D type names rather than these aliases throughout SDWF.

Must confess, I'm new to D, and so far impressed with what I see. However, I
am definintely
not new to Windows API programming, been doing that since Windows 2.0, and
from that
perspective having the Windows typenames available makes a lot of sense -
otherwise you end
in the VB scenario of looking up something in the platform API, working what
'D' type to use for
the appropriate function - I'd much prefer a predictable mapping.

>> Which is more readable/understandable?
>>
>>     extern (Windows) LRESULT windowCallback(HWND hWnd, UINT uMsg, WPARAM
>> wParam, LPARAM lParam)
>>
>> or
>>
>>     typedef void* Handle = (void*)0; // a typedef, but a useful one
>>     extern (Windows) int windowCallback(Handle handle, uint message, uint
>> param1, int param2)
>
> I think we both agree on this.

Me too, but think it would slow down a lot of Windows developers (myself included).

Hope these comments are useful - at least worth a moments consideration.

Rob


March 02, 2005
On Wed, 2 Mar 2005 02:21:51 -0000, Rob Grainger <nospam@nospam.com> wrote:
> Again, the purpose here is not to be cross-language (these kind of names
> never made an
> appearance in VB), but to support C compilers where the basic types have
> different sizes
> (a rare occurence on Windows, but theoretically possible) - all such a
> compiler-vendor
> would need to do is define a few thousand typedef's appropiately (that was
> sarcasm).

Ok, so given that D does not have different sized basic types, but fixed sized basic types, what do you recommend we do here?

I believe the point you were making is that on some systems pointers are 32bit, and others 64bit, and you need a type that will definately hold a pointer.

D can do this with typedef, or alias, eg.

version(32bit) {
  typedef ptr_t uint
}
version(64bit) {
  typedef ptr_t ulong
}

or similar. What do you think?

Regan
March 02, 2005
Regan,

Yes, that's exactly the approach I'd recommend. Closest in concept to the
Win32 approach, so
more familiar to Win API programmers.

Rob

"Regan Heath" <regan@netwin.co.nz> wrote in message news:opsmzpakfh23k2f5@ally...
> On Wed, 2 Mar 2005 02:21:51 -0000, Rob Grainger <nospam@nospam.com> wrote:
>> Again, the purpose here is not to be cross-language (these kind of names
>> never made an
>> appearance in VB), but to support C compilers where the basic types have
>> different sizes
>> (a rare occurence on Windows, but theoretically possible) - all such a
>> compiler-vendor
>> would need to do is define a few thousand typedef's appropiately (that
>> was
>> sarcasm).
>
> Ok, so given that D does not have different sized basic types, but fixed sized basic types, what do you recommend we do here?
>
> I believe the point you were making is that on some systems pointers are 32bit, and others 64bit, and you need a type that will definately hold a pointer.
>
> D can do this with typedef, or alias, eg.
>
> version(32bit) {
>   typedef ptr_t uint
> }
> version(64bit) {
>   typedef ptr_t ulong
> }
>
> or similar. What do you think?
>
> Regan


March 02, 2005
Regan,

As a brief postscript, I do like the increased type safety typedef gives -
its
always annoyed me in C++ not being able to overload on different typedef's.

As long as there no interactions at ABI level to prevent this, making alias a better choice.

Rob

"Rob Grainger" <nospam@nospam.com> wrote in message news:d03ah5$1jl1$1@digitaldaemon.com...
> Regan,
>
> Yes, that's exactly the approach I'd recommend. Closest in concept to the
> Win32 approach, so
> more familiar to Win API programmers.
>
> Rob
>
> "Regan Heath" <regan@netwin.co.nz> wrote in message news:opsmzpakfh23k2f5@ally...
>> On Wed, 2 Mar 2005 02:21:51 -0000, Rob Grainger <nospam@nospam.com> wrote:
>>> Again, the purpose here is not to be cross-language (these kind of names
>>> never made an
>>> appearance in VB), but to support C compilers where the basic types have
>>> different sizes
>>> (a rare occurence on Windows, but theoretically possible) - all such a
>>> compiler-vendor
>>> would need to do is define a few thousand typedef's appropiately (that
>>> was
>>> sarcasm).
>>
>> Ok, so given that D does not have different sized basic types, but fixed sized basic types, what do you recommend we do here?
>>
>> I believe the point you were making is that on some systems pointers are 32bit, and others 64bit, and you need a type that will definately hold a pointer.
>>
>> D can do this with typedef, or alias, eg.
>>
>> version(32bit) {
>>   typedef ptr_t uint
>> }
>> version(64bit) {
>>   typedef ptr_t ulong
>> }
>>
>> or similar. What do you think?
>>
>> Regan
>
> 


March 02, 2005
On Wed, 02 Mar 2005 16:00:10 +1300, Regan Heath wrote:

> On Wed, 2 Mar 2005 02:21:51 -0000, Rob Grainger <nospam@nospam.com> wrote:
>> Again, the purpose here is not to be cross-language (these kind of names
>> never made an
>> appearance in VB), but to support C compilers where the basic types have
>> different sizes
>> (a rare occurence on Windows, but theoretically possible) - all such a
>> compiler-vendor
>> would need to do is define a few thousand typedef's appropiately (that
>> was
>> sarcasm).
> 
> Ok, so given that D does not have different sized basic types, but fixed sized basic types, what do you recommend we do here?
> 
> I believe the point you were making is that on some systems pointers are 32bit, and others 64bit, and you need a type that will definately hold a pointer.
> 
> D can do this with typedef, or alias, eg.
> 
> version(32bit) {
>    typedef ptr_t uint
> }
> version(64bit) {
>    typedef ptr_t ulong
> }
> 
> or similar. What do you think?
> 
> Regan

Just letting you know that in object.d we already have ...

version (AMD64)
{
    alias ulong size_t;
    alias long ptrdiff_t;
}
else version (X86)
{
    alias uint size_t;
    alias int ptrdiff_t;
}

Which probably means all you need to do is ...

  alias size_t ptr_t;

-- 
Derek
Melbourne, Australia
2/03/2005 2:26:46 PM
March 02, 2005
On Wed, 2 Mar 2005 14:28:34 +1100, Derek Parnell <derek@psych.ward> wrote:
> On Wed, 02 Mar 2005 16:00:10 +1300, Regan Heath wrote:
>
>> On Wed, 2 Mar 2005 02:21:51 -0000, Rob Grainger <nospam@nospam.com> wrote:
>>> Again, the purpose here is not to be cross-language (these kind of names
>>> never made an
>>> appearance in VB), but to support C compilers where the basic types have
>>> different sizes
>>> (a rare occurence on Windows, but theoretically possible) - all such a
>>> compiler-vendor
>>> would need to do is define a few thousand typedef's appropiately (that
>>> was
>>> sarcasm).
>>
>> Ok, so given that D does not have different sized basic types, but fixed
>> sized basic types, what do you recommend we do here?
>>
>> I believe the point you were making is that on some systems pointers are
>> 32bit, and others 64bit, and you need a type that will definately hold a
>> pointer.
>>
>> D can do this with typedef, or alias, eg.
>>
>> version(32bit) {
>>    typedef ptr_t uint
>> }
>> version(64bit) {
>>    typedef ptr_t ulong
>> }
>>
>> or similar. What do you think?
>>
>> Regan
>
> Just letting you know that in object.d we already have ...

Thanks Derek, I had forgotten where this was.

> version (AMD64)
> {
>     alias ulong size_t;
>     alias long ptrdiff_t;
> }
> else version (X86)
> {
>     alias uint size_t;
>     alias int ptrdiff_t;
> }
>
> Which probably means all you need to do is ...
>
>   alias size_t ptr_t;

Or perhaps we want/need to add ptrsize_t to object.d?

Regan