Call C variadic function from D variadic function
ag0aep6g
anonymous at example.com
Sun Sep 13 18:35:48 UTC 2020
> ```
> /// Add a single line to an existing header
> auto addLine(T...)(RecordType type, T kvargs)
> if(kvargs.length > 0 && isSomeString!(T[0]))
> {
> static assert (kvargs.length %2 == 0); // K-V pairs => even
> number of variadic args
>
> string varargMagic(size_t len)
> {
> string args = "sam_hdr_add_line(this.h, type.ptr, ";
> for(int i=0; i<len; i++)
> args ~= "toStringz(kvargs[" ~ i.to!string ~ "]), ";
> args ~= "null)";
> return args;
> }
>
> return mixin(varargMagic(kvargs.length));
> }
> ```
[...]
> Question:
> If a variadic template, despite presenting to the user a "dynamic
> array", MUST know its parameter list at compile-time, is there a way
> (other than with mixins as shown) to pass this parameter list to
> extern(C) linkage function with variadic parameters?
Easy peasy:
import std.meta: Repeat;
Repeat!(kvargs.length, const(char)*) zs;
foreach (i, ref z; zs) z = toStringz(kvargs[i]);
return sam_hdr_add_line(this.h, type.ptr, zs, null);
By the way, `kvargs` is not a dynamic array. Its length is not dynamic,
and it's not an array.
Also, you don't just want to pass the parameters forward. That would be
trivial: `sam_hdr_add_line(this.h, type.ptr, kvargs, null)`. You want to
run them through another function first. That's where the difficulty
comes from.
> (bonus question: if yes, can it be done with typesafe variadic function
> where I believe parameter list is known at either compile time OR
> runtime, depending on how called)
I don't see when it would matter how the function is called, but you can
declare it in two different ways:
1) True typesafe variadic:
auto addLine(RecordType type, string[] kvargs ...)
2) Template + typesafe variadic:
auto addLine(size_t n)(RecordType type, string[n] kvargs ...)
In the first one, `kvargs.length` is a dynamic value. You can't use it
to generate the arguments for a `sam_hdr_add_line` call.
In the second one, `kvargs.length` is a static value. So you can do the
same things as in the `T...` template. And just like the `T...`
template, it will generate a new function for every distinct
`kvargs.length`.
More information about the Digitalmars-d-learn
mailing list