On Tuesday, 12 January 2016 at 14:10:02 UTC, John Colvin wrote:
On Tuesday, 12 January 2016 at 13:24:48 UTC, Russel Winder
wrote:
On Tue, 2016-01-12 at 11:05 +0000, John Colvin via
Digitalmars-d wrote:
[…]
What's so hard about writing a few function prototypes,
aliases and enums? It's annoying that we have to do it, but
compared to writing the rest of a project it's always going
to be a tiny amount of work.
I started there but gave up quite quickly as there are two
levels of API here, both of which are needed to use the
higher-level API as it refers directly to low-level structs
and stuff.
There is the kernel device drivers level, which defines the
low-level API, and then there is libdvd5 which provides a
(slightly) higher C API – with all the idiocies of a C API for
doing high-level library programming :-(
I have found a Rust wrapper of the kernel API, but that would
mean writing all the libdvbv5 equivalent myself before writing
the application code. There is no equivalent D version and
certainly no easy way of wrapping libdvbv5 in D without it. Go
has problems with C APIs and no sensible GTK3 wrapper.
For a lot of projects you can only bind what you actually
need, I often just pretend that I have already written the
bindings then write whatever lines are necessary to get it to
compile!
The problem is that this is easy in C++ for a C API, but not
for D or Rust using the same C API. C++ can use the C stuff
directly, D and Rust need an adaptor.
I agree it's easier in C++, but what I mean is literally doing
something like:
1) write code pretending you've got complete bindings
2) try to compile
3) write the bare minimum bindings necessary to make it compile
4) goto 1
It's amazing how little of an API often ends up being used and
therefore how little binding code you have to write.
Alternatively you can write the bindings immediately when you
use them, but I prefer not having to do the context switch
between writing application and bindings quite as often as that.
It's a nice technique that I hadn't thought about, and I'll
definitely try it.
I won't always work, though. At work we write our own operating
systems with loooooads of platform headers. Every function
definition depends on struct definitions that are in other
headers which are generated from macros that.... you get the
point.
Unless, of course, I give up on accessing struct members from D,
pass everything as void* and write C accessors. Which is a pain,
especially compared to:
extern "C" {
#include "foo.h"
#include "bar.h"
}
Atila