digitalmars.D.learn - Wrapping c variadic functions
- simendsjo (16/16) Feb 23 2012 Say i have a c function (didn't include first format argument for
- simendsjo (3/19) Feb 23 2012 My bad. The first version works just fine. I passed a float and had the ...
- James Miller (9/25) Feb 23 2012 I'm pretty sure that std.c.stdarg is where you want to go,
- Artur Skawina (42/61) Feb 23 2012 You may want to check if a va_list based version of the C function is av...
- simendsjo (12/79) Feb 23 2012 Hmm. Didn't my previous post make it to the newsgroup? Is visible at my ...
- Artur Skawina (4/5) Feb 23 2012 The mailing list gets stuck sometimes and does not forward messages for ...
- H. S. Teoh (7/14) Feb 23 2012 My MX was getting Disk Full errors from the primary SMTP server.
- Brad Roberts (5/17) Feb 23 2012 The interruptions to mail flow have actually been driven by the
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.
Feb 23 2012
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...
Feb 23 2012
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) { =C2=A0 =C2=A0print(args); // only the first argument is printed } void print(...) { =C2=A0 =C2=A0print(_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...
Feb 23 2012
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
Feb 23 2012
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: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 }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
Feb 23 2012
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
Feb 23 2012
On Thu, Feb 23, 2012 at 08:53:00PM +0100, Artur Skawina wrote:On 02/23/12 20:37, simendsjo wrote: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 WirchenkoHmm. 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...
Feb 23 2012
On Thu, 23 Feb 2012, H. S. Teoh wrote:On Thu, Feb 23, 2012 at 08:53:00PM +0100, Artur Skawina wrote: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.On 02/23/12 20:37, simendsjo wrote: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. :)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...
Feb 23 2012