Thread overview | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
February 23, 2012 Wrapping c variadic functions | ||||
---|---|---|---|---|
| ||||
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. |
February 23, 2012 Re: Wrapping c variadic functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to simendsjo | On Thu, 23 Feb 2012 11:35:32 +0100, simendsjo <simendsjo@gmail.com> 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.
My bad. The first version works just fine. I passed a float and had the format string as %d...
|
February 23, 2012 Re: Wrapping c variadic functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to simendsjo | On 23 February 2012 23:35, simendsjo <simendsjo@gmail.com> 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.
I'm pretty sure that std.c.stdarg is where you want to go, unfortunately, due to the fact that C varargs is a bit of black magic, you can only really wrap functions that provide v* versions. On top of that, std.c.stdarg is just a wrapper for the C library of the same name, so it doesn't provide a proper way to convert anything to a va_list.
However, if you experiment with v* functions from C, then you might be able to trick it...
|
February 23, 2012 Re: Wrapping c variadic functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to simendsjo | 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 |
February 23, 2012 Re: Wrapping c variadic functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Artur Skawina | On Thu, 23 Feb 2012 18:42:51 +0100, Artur Skawina <art.08.09@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
}
|
February 23, 2012 Re: Wrapping c variadic functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to simendsjo | On 02/23/12 20:37, simendsjo wrote:
> Hmm. Didn't my previous post make it to the newsgroup? Is visible at my end.
The mailing list gets stuck sometimes and does not forward messages for hours. Your question made it, but the later post only arrived here minutes ago...
artur
|
February 23, 2012 Re: Wrapping c variadic functions | ||||
---|---|---|---|---|
| ||||
On Thu, Feb 23, 2012 at 08:53:00PM +0100, Artur Skawina wrote: > On 02/23/12 20:37, simendsjo wrote: > > Hmm. Didn't my previous post make it to the newsgroup? Is visible at my end. > > The mailing list gets stuck sometimes and does not forward messages for hours. Your question made it, but the later post only arrived here minutes ago... My MX was getting Disk Full errors from the primary SMTP server. Probably traffic on D mailing lists is too high for the mailing list to handle. :) T -- Computerese Irregular Verb Conjugation: I have preferences. You have biases. He/She has prejudices. -- Gene Wirchenko |
February 23, 2012 Re: Wrapping c variadic functions | ||||
---|---|---|---|---|
| ||||
On Thu, 23 Feb 2012, H. S. Teoh wrote:
> On Thu, Feb 23, 2012 at 08:53:00PM +0100, Artur Skawina wrote:
> > On 02/23/12 20:37, simendsjo wrote:
> > > Hmm. Didn't my previous post make it to the newsgroup? Is visible at my end.
> >
> > The mailing list gets stuck sometimes and does not forward messages for hours. Your question made it, but the later post only arrived here minutes ago...
>
> My MX was getting Disk Full errors from the primary SMTP server. Probably traffic on D mailing lists is too high for the mailing list to handle. :)
The interruptions to mail flow have actually been driven by the auto-tester filling up the disks periodically. I'm going to have to separate the tester off onto a different box to avoid the problem I think. Anyway, sorry for the interruption.
|
Copyright © 1999-2021 by the D Language Foundation