Thanks! I never received any notification that it was publicly
accessible now.
Just a note for anyone who's already read the blog series. This
is the same material, just updated, corrected and edited
together. Please prefer this to the blog posts when referring
people to it.

Thanks! I never received any notification that it was publicly
accessible now.
Just a note for anyone who's already read the blog series. This is the
same material, just updated, corrected and edited together. Please
prefer this to the blog posts when referring people to it.

It's a good article. I haven't read it completely to the end but I would
like to mention a few things.
You didn't mention macros, global variables or inline functions. I think
I've seen inline functions somewhere.
Global Variables
Global variables need to have an extra "extern" and the __gshared
storage. Example in C:
int a;
Translated to D:
extern (C) extern __gshared int a;
For TLS variables __gshared is not used.
Typedefs
When I do a binding I'm trying to figure out why they used a typedef in
the first place. There's a couple of reasons:
* To get a fixed type on all platforms. In the C language there are no
fixed types, it's just relations between the sizes of the types. I.e.
long => int => short => char, or something like that.
In this case, use the native D type. In D a given type has a fixed size
on all platforms (except for real). Examples of these can be: "int8_t",
"uint16_t", "uint32_t" and so on.
* To get different sizes on different platforms. For example, a 32bit
value of 32bit platforms and a 64bit value of 64bit platforms. In this
case you're basically forced to use an alias.
* Opaque types. Perhaps the API is hiding the actual type behind a void*
or for other reasons uses a void*. Then it uses a tyepdef on top of that
to give it an idea of what type we're dealing with.
In this case use the typedef.
* The typedef is well known in the API. Examples of this would be GLint.
I don't remember why they use typedefs but if I recall correctly GLint
is used in all examples, tutorials, books and so on.
In this case it's best to the typedef.
* Hiding a complex type. An example of this could be function pointers.
In this case use the typedef.
Function pointers
With function pointers there are (at least) two cases where an alias
have to be used, instead of a function pointer.
* When declaring function parameters with a specific linkage. The
following is syntactically invalid in D:
void foo (extern(C) void function () callback);
Use an alias:
alias extern (C) void function () Callback;
void foo (Callback callback);
* When using a cast with a specific linkage. You won't see this in a
binding, if you're not converting inline functions. This is invalid in D
as well:
void* foo;
...
auto bar = cast(extern (C) void function ()) foo;
Use the same approach as above.
Structs/Unions
You actually didn't mention unions at all but basically all the same
rules that apply when translating structs apply to unions as well. Two
other things that you didn't mention was nested structs and anonymous
structs.
Structs
* For named structs in typedefs I feel a bit undecided of how I want to
have it. You can either just use the name of the typedef in D when
declaring the struct. Or you can use the real name of the struct and
then use an alias as well. In some cases the actual name of the struct
could be used, i.e. "struct foo".
Anonymous Structs
* If an anonymous struct is used directly to declare a variable you're
forced to invent a name for the struct in D, since D doesn't support
anonymous structs. Example:
struct
{
int a;
int b;
} c;
Translate to:
struct _AnonymousStruct1
{
int a;
int b;
}
_AnonymousStruct1 c;
Any name can be used in this case. In my tool, DStep, for automatically
generating bindings I'm using names similar to above.
* If an anonymous struct is used in a typedef just use the name of the
typedef. No alias is required in the D code in this case. I actual
noticed now that you have this example.
Nested structs
I always fail to remember how these should be translated to D.
* For nested structs that are named. Example:
struct Foo
{
int a;
struct Bar
{
int b;
} bar;
}
In this case translate it to a named struct in D as well:
struct Foo
{
int a;
struct Bar
{
int b;
}
Bar bar;
}
* For nested struct that are anonymous. Example:
struct Foo
{
int a;
struct
{
int b;
} bar;
}
In this case you could translate it to an anonymous struct in D as well:
struct Foo
{
int a;
struct
{
int b;
}
}
The problem with this is that the API changes. Instead of accessing "b"
like this:
struct Foo foo;
foo.bar.b = 1;
You would do like this:
Foo foo;
foo.b = 1;
I actually looked at the documentation now and see that this example is
not used anymore:
http://dlang.org/interfaceToC.htmlhttp://dlang.org/htod.html
It's still on the D1 page:
http://digitalmars.com/d/1.0/htomodule.html
--
/Jacob Carlborg

On Fri, 17 May 2013 08:44:14 +0100, Jacob Carlborg <doob me.com> wrote:
.. lots of great things. Can we get all the advice from the article and
these replies onto a D wiki or howto page pls. If someone can point me to
where to add it, I can do a rough copy/paste. Assuming both authors are
happy with this..
R
--
Using Opera's revolutionary email client: http://www.opera.com/mail/

On Fri, 17 May 2013 08:44:14 +0100, Jacob Carlborg <doob me.com> wrote:
.. lots of great things. Can we get all the advice from the article and
these replies onto a D wiki or howto page pls. If someone can point me
to where to add it, I can do a rough copy/paste. Assuming both authors
are happy with this..

On Fri, 17 May 2013 08:44:14 +0100, Jacob Carlborg <doob me.com> wrote:
.. lots of great things. Can we get all the advice from the article and
these replies onto a D wiki or howto page pls. If someone can point me
to where to add it, I can do a rough copy/paste. Assuming both authors
are happy with this..

Hmm. I see you just copy pasted my answer. It fits as an answer in a
newsgroup like this. But I don't think it fits in that format in the
wiki.

That's what I said I'd do.. it's all I have time for.
I think having the info there, even if it doesn't necessarily "follow" is
better than not.
Someone with more time can improve upon it.
R
--
Using Opera's revolutionary email client: http://www.opera.com/mail/