Call C variadic function from D variadic function

James Blachly james.blachly at
Sun Sep 13 18:56:52 UTC 2020

On 9/13/20 2:35 PM, ag0aep6g wrote:
> 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);
Great, thank you!

> By the way, `kvargs` is not a dynamic array. Its length is not dynamic, 
> and it's not an array.

I was incorrectly recalling the error message compiler emitted when 
using the typesafe variadic FUNCTION (your method 1, below)

> 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.

Right, I indeed left that out of the problem statement; the trivial 
variadic template params pass right on through which is awesome.

> I don't see when it would matter how the function is called, but you can 
> declare it in two different ways:

My assumption is that if called passing a [runtime] dynamic array, of 
course the parameter list cannot be known, but the (below) "Type 1 True 
typesafe variadic" can also be called with a fixed parameter list known 
at compile-time.

> 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.

My point of surprise was that -- depending on how invoked ( f(anArray) 
versus f(1,2,3) the compiler may know at compile-time the parameter 
list. But from a complexity standpoint it makes sense that it is 
nonetheless not possible to use.

> 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`.

Great, I never thought of parameterizing as a static array. This looks 
the best IMO.

More information about the Digitalmars-d-learn mailing list