On Thursday, 23 November 2017 at 11:35:18 UTC, Skuzzi wrote:
typedef void (__stdcall* _function) (const char *text);
I want to do this in D. I understand that D uses "extern (C)"
and does away with specifying calling conventions. However, how
does D know the calling convention required? What if it is a
__thiscall or something else, will it always be handled
properly by D, just be specifying "extern (C)"?
extern(C) is for __cdecl functions. For __stdcall, it is
`extern(Windows)`.
D doesn't actually do away with calling conventions, it just
specifies them with slightly different syntax. You do still wanna
make sure you get the right one.
Does anyone know of a proper and recommended way to achieve
this in D?
Generally speaking, if you can do it in C or C++, it isn't *that*
much different to do in D: the concepts are the same, just the
syntax is slightly different.
So the C function pointer (*foo)(arg) stuff turns into a D
function pointer: `return_type function(args)` where `function`
is the literal keyword `function`. The calling convention turns
into one of the correct `extern` on the outside of it:
`extern(C)`, `extern(C++)`, `extern(Windows)`, `extern(Pascal)`,
or extern(System) and, for completeness, extern(D). The name is
based on which language uses that calling convention by default.
Then casts go from (type)(statement) to `cast(type)(statement)`;
the addition of the `cast` keyword.
And a few other little things like array from `int foo[]` to
`int* foo` - use pointers for calling C functions instead of D
arrays. and C's `long` is not the same as D's `long`, use `import
core.stdc.config;` and the type `c_long` instead.
otherwise... pretty straightforward one-to-one translation of the
concepts described in C++ on the 'net over to D syntax should get
you there. You can call the same Windows API functions too.