Wrapping c variadic functions
Artur Skawina
art.08.09 at gmail.com
Thu Feb 23 09:42:51 PST 2012
On 02/23/12 11:35, simendsjo wrote:
> Say i have a c function (didn't include first format argument for simplicity)
>
> void print(...);
> I wrap it up:
> extern(System) void print(...);
>
> And then I try to wrap it up in some safer D way:
> void print(Args...)(Args args)
> {
> print(args); // only the first argument is printed
> }
>
> void print(...)
> {
> print(_argptr); // no go either
> }
>
> How am I supposed to do this? http://dlang.org/function.html#variadic doesn't make my any smarter.
>
You may want to check if a va_list based version of the C function is available.
Anyway, the above should work, with a valid C prototype; this works here:
------------------------------------------------------------------------------------------
import std.string;
extern (C) int printf(const char*, ...);
int dp(A...)(A args) { return printf(args); }
void main(string[] argv) {
dp(cast(char*)"%s\n", argv[0].toStringz);
dp(cast(char*)"%s, %s\n", argv[0].toStringz, argv[1].toStringz);
dp(cast(char*)"%s, %s, %s\n", argv[0].toStringz, argv[1].toStringz, argv[2].toStringz);
dp(cast(char*)"%s, %d, %s\n", argv[0].toStringz, 42, argv[2].toStringz);
}
------------------------------------------------------------------------------------------
and you can even do things like:
------------------------------------------------------------------------------------------
import std.string;
import std.typetuple;
extern (C) int printf(const char*, ...);
int dp(A...)(A args) {
alias ReplaceAll!(immutable(char)[], char*, A) CA;
CA cargs;
foreach (i, arg; args) {
static if (is(typeof(arg):const(char)[]))
cargs[i] = cast(char*)arg.toStringz;
else
cargs[i] = arg;
}
return printf(cargs);
}
void main(string[] argv) {
dp("%s\n", argv[0]);
dp("%s, %s\n", argv[0], argv[1]);
dp("%s, %s, %s\n", argv[0], argv[1], argv[2]);
dp("%s, %d, %s\n", argv[0], 42, argv[2]);
}
------------------------------------------------------------------------------------------
to expose a more sane API.
Note: this example only handles D strings.
BTW, is there a simpler and/or more generic way to achieve this? Thinking about
using it in C bindings...
artur
More information about the Digitalmars-d-learn
mailing list