Call C variadic function from D variadic function

James Blachly james.blachly at gmail.com
Sun Sep 13 16:55:33 UTC 2020


Summary:
Can a typesafe D variadic function, or D variadic template pass its 
parameters to a C variadic function?

Background:
I maintain a library binding [0] to htslib, a high-performance and very 
widely used C library for high-throughput sequencing (hts) data files. 
We use this internally and haven't polished it for a release on the 
announce forum or biomed twitter, etc. yet.

In the course of upgrading it to support the latest API/ABI (htslib-1.10 
/ so.3), I need to add support for several new functions.

One of these is a variadic function with the signature:

`int sam_hdr_add_line(sam_hdr_t *h, const char *type, ...);`

Of course, we can call this directly from D with hardcoded parameters. 
However, one of the focuses of our library is "bindings + wrappers" to 
make this feel more like native D. Thus, we want a variadic function to 
which we may pass D strings (it is also a struct member function).

With help from Herringway on IRC, we came up with a solution using mixin:


```
     /// 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?


(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)


Thanks all in advance



[0] dhtslib
https://code.dlang.org/packages/dhtslib
https://github.com/blachlylab/dhtslib

[1] https://dlang.org/spec/expression.html#expression


More information about the Digitalmars-d-learn mailing list