February 28, 2005 Re: Windows API headers again (slightly OT) | ||||
---|---|---|---|---|
| ||||
Posted in reply to John C | 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 Re: Windows API headers again (slightly OT) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stewart Gordon | "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 Re: Windows API headers again (slightly OT) | ||||
---|---|---|---|---|
| ||||
Posted in reply to John C | "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 Re: Windows API headers again (slightly OT) | ||||
---|---|---|---|---|
| ||||
Posted in reply to John C | 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 Re: Windows API headers again (slightly OT) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stewart Gordon | 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 Re: Windows API headers again (slightly OT) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rob Grainger | 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 Re: Windows API headers again (slightly OT) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | 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 Re: Windows API headers again (slightly OT) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rob Grainger | 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 Re: Windows API headers again (slightly OT) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | 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 Re: Windows API headers again (slightly OT) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | 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 |
Copyright © 1999-2021 by the D Language Foundation