Wrapping C code?

anonymous anonymous at example.com
Sat Mar 29 15:47:03 PDT 2014


On Saturday, 29 March 2014 at 21:30:03 UTC, CJS wrote:
>> Well, you can write one. You can also let D generate that list:
>> __traits(allMembers, some_c_module) gives you all symbols in
>> some_c_module.
[...]
> I don't understand how that is possible. The C code I have 
> available is a compiled library and its headers, so libfoo.a 
> (or libfoo.so) and foo.h. I've compiled D calling C before by 
> declaring the C function inside D code and then linking 
> libfoo.a to the compiled D code.
>
> Can you provide a short example of how this would work?

Maybe I worded that a bit misleading. You do need those
declarations in D. There's no simple solution with just a C
header. But there is a tool that translates C headers to D:
dstep. I didn't use it myself yet, so I can't comment on its
quality. Alternatively, make the declarations manually, as you
did so far. Put them in a separate module. That's some_c_module
(.d or .di), which looks something like this:

---
module some_c_module;
extern(C): /* or maybe extern(System) */
void XXXXaction(context, arg1, arg2);
/* ... etc ... */
---

And here's one version how to generate aliases without the prefix:

---
import std.algorithm: joiner, map, startsWith;
import std.conv: to;
import std.string: chompPrefix;
string aliasPrefixAway(string symbol, string prefix)
{
       return symbol.startsWith(prefix) && symbol != prefix
           ? "alias " ~ symbol.chompPrefix(prefix) ~ " = " ~ symbol
~ ";"
           : "";
}
string aliasPrefixAway(string[] symbols, string prefix)
{
       return symbols.map!(s => aliasPrefixAway(s,
prefix)).joiner.to!string;
}
import some_c_module;
mixin(aliasPrefixAway([__traits(allMembers, some_c_module)],
"XXXX"));
/* action is an alias of XXXXaction now. */
---

Most of that is just string fiddling, generating D code. The more
interesting parts are __traits(allMembers, ...) and the string
mixin.


More information about the Digitalmars-d-learn mailing list