The future of the WindowsAPI bindings project
Stewart Gordon
smjg_1998 at yahoo.com
Sun May 13 08:07:09 PDT 2012
There's been another call for the Windows API bindings to be put into druntime. But
before we do, a few things need to be thought about:
1. What are we going to do with the HANDLE type? There was a thread about it in February
but no decision was reached.
What we want is:
(a) HANDLE to be a distinct type from void* or any constancy variation thereof
(b) specific handle types to be implicitly convertible to HANDLE, but not arbitrarily
interconvertible
(c) other handle types to act as subtypes of specific handle types, such as HGDIOBJ.
The MinGW headers, if STRICT is defined, implement (b), but not (a), and use a workaround
to try to get as near to (c) as possible.
I've refined my earlier solution, and this is what I have now.
----------
version (D_Version2) {
struct HANDLE__(T) {
T t__;
mixin("alias t__ this;");
typeof(this) opAssign(typeof(this) t) { t__ = t.t__; return this; }
}
mixin("alias HANDLE__!(const(void)*) HANDLE;");
} else {
template HANDLE__(T) {
mixin("typedef T HANDLE__;");
}
mixin("typedef void* HANDLE;");
}
template DECLARE_HANDLE(string name, string base = "HANDLE") {
mixin("alias HANDLE__!(" ~ base ~ ") " ~ name ~ ";");
}
// example declarations using it
mixin DECLARE_HANDLE!("HWND");
mixin DECLARE_HANDLE!("HGDIOBJ");
mixin DECLARE_HANDLE!("HPEN", "HGDIOBJ");
----------
2. An annoyance is the need for .lib files generated from the bindings in order to support
those functions that are #define directives in the C headers. Ellery Newcomer has
suggested getting around this by making them nullary templates
-WORD MAKELANGID(USHORT p, USHORT s) { return cast(WORD)((s << 10) | p); }
+WORD MAKELANGID()(USHORT p, USHORT s) { return cast(WORD)((s << 10) | p); }
since this way the function will be compiled on demand (presumably inlined when it's a
simple function like this).
3. Windows 9x support has been officially discontinued in the D2 line. Indeed, it's been
reported that programs compiled with recent DMD2 versions won't run under Win9x. Keeping
in the versioning for Win9x enables those D1 programmers that remain to write stuff that
runs under Win9x. But it does complicate the code quite a bit, and D1 will be
discontinued at the end of the year anyway.
On this basis, what should we do? Indeed, what exactly is D2's official minimum supported
version of Windows? Me, NT4 or 2000?
Advantages of keeping the Win9x versioning in the bindings:
- Enables those D1 programmers that remain to write stuff that runs under Win9x.
- Saves the effort of going through removing it
Advantages of getting rid of it:
- Makes the bindings less complicated, as we no longer need to worry about the separate
_WIN32_WINDOWS and _WIN32_WINNT constants
- Less work for people translating the headers
- Would reduce the temptation to try writing a Win9x app in D2
Of course, when the bindings are put into druntime, it would make most sense to put in a
version with this Win9x and D1/D2 versioning removed. But for as long as we still have
both D versions to support....
Anyway, I'm inclined to implement the solutions proposed for points 1 and 2. And of
course update the translation instructions accordingly.
Any objections?
Stewart.
More information about the Digitalmars-d
mailing list