Thread overview | ||||||
---|---|---|---|---|---|---|
|
December 09, 2014 Can someone explain why this outputs garbage values? | ||||
---|---|---|---|---|
| ||||
I'm trying to work with some c functions that make use of varargs and I'm trying to push my d varargs to c varargs. http://dpaste.dzfl.pl/ad08a6197963 Code: ___________________________________________________ import core.vararg; import std.string : toStringz; import std.c.stdio; char[256] buffer; void print(string format, ...) { char* dest = buffer.ptr; snprintf(dest, 256UL, toStringz(fmt), _argptr); printf(dest); } void main(string[] args) { print("%d, %d, %d\n", 1, 2, 3); } ___________________________________________________ Output: -1080890848, 1073915632, 3 |
December 09, 2014 Re: Can someone explain why this outputs garbage values? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dustin | On Tuesday, 9 December 2014 at 19:44:42 UTC, Dustin wrote:
> snprintf(dest, 256UL, toStringz(fmt), _argptr);
To forward varargs in C, you need to use a different function: vsnprintf instead of snprintf. (The new v at the beginning means varargs).
I don't think that's completely compatible with D's varargs though, the type C expects is va_list, it might be on core.vararg, I'm not sure.
|
December 09, 2014 Re: Can someone explain why this outputs garbage values? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dustin | Also, the reason why the special function is needed is that the argptr is just a pointer to the arguments. If you pass that to printf, how does it know that there's varargs on the other end instead of just being another pointer whose numeric value it is supposed to print out? |
December 09, 2014 Re: Can someone explain why this outputs garbage values? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | On Tuesday, 9 December 2014 at 20:24:18 UTC, Adam D. Ruppe wrote: > Also, the reason why the special function is needed is that the argptr is just a pointer to the arguments. If you pass that to printf, how does it know that there's varargs on the other end instead of just being another pointer whose numeric value it is supposed to print out? I got it to work with vsnprintf with the following code: ___________________________________________________ import core.vararg; import std.string : toStringz; import std.c.stdio : printf; char[256] buffer; extern(C) void vsnprintf(char* s, ulong n, const(char*) format, va_list arg); void print(string fmt, ...) { char* dest = buffer.ptr; va_list list; va_start(list, fmt); vsnprintf(dest, 256UL, toStringz(fmt), list); printf(dest); } void main(string[] args) { print("%d, %d, %d\n", 1, 2, 3); } ___________________________________________________ I did have to declare my own function prototype because importing vsnprintf from std.c.stdio produced the following error: "test.d(13): Error: function core.stdc.stdio._vsnprintf (char* s, ulong n, const(char*) format, __va_list_tag* arg) is not callable using argument types (char*, ulong, immutable(char)*, char*)" It works fine with my own function declaration though... (I'm using LDC on Win64) |
Copyright © 1999-2021 by the D Language Foundation