Call C variadic function from D variadic function
Paul Backus
snarwin at gmail.com
Sun Sep 13 18:35:27 UTC 2020
On Sunday, 13 September 2020 at 17:23:42 UTC, Steven
Schveighoffer wrote:
> On 9/13/20 12:55 PM, James Blachly wrote:
>>
>> ```
>> /// 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));
>> }
>> ```
>>
>> Interestingly, compilation fails if the mixin consists only of
>> the comma-separated parameters ("Comma expression" [1])
>>
>>
>> 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?
>
> Was just talking about this exact problem with Adam Ruppe.
> Unfortunately, because the parameters are an expression tuple,
> and not a compile-time tuple, you can't use stuff like
> staticMap.
You actually can, if you define the right kind of helper function:
/// 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
immtuable(char)* argToStringz(alias arg)()
{
return toStringz(arg);
}
return sam_hdr_add_line(this.h, this.ptr,
staticMap!(argToStringz, kvargs), null);
}
The clever trick here is that, because of optional parentheses
[1], `argToStringz!(kvargs[i])` can be interpreted either as the
name of a function or a function call, depending on the context
it appears in.
[1] https://dlang.org/spec/function.html#optional-parenthesis
More information about the Digitalmars-d-learn
mailing list