On Thu, 23 Feb 2012 18:42:51 +0100, Artur Skawina <art.08...@gmail.com> wrote:

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

Hmm. Didn't my previous post make it to the newsgroup? Is visible at my end.
I wrote: "
My bad. The first version works just fine. I passed a float and had the format string as %d..."

So
print(Args...)(Args args)
{
  c_print(args); // works just fine
}

Reply via email to