digitalmars.D.learn - Problem Passing Struct to C
- Mike Parker (21/21) May 06 2011 Testing out a new binding I knocked up for a C library. One of the
- Steven Schveighoffer (18/40) May 06 2011 There are two possible causes I can think of, depending on how draw_text...
- Mike Parker (13/60) May 06 2011 It's a pointer to a function symbol in a DLL. In Derelict, all functions...
- Jacob Carlborg (7/29) May 06 2011 You need to convert the string into a C string;
- Steven Schveighoffer (4/38) May 06 2011 No, D implicitly casts string literals to zero-terminated const(char)*. ...
- Mike Parker (10/50) May 06 2011 toStringz was actually the first thing I went for when I got the
- Jacob Carlborg (4/45) May 06 2011 Since when?
- Robert Clipsham (6/11) May 06 2011 Since const was introduced, before then they implicitly casted to char*
- Jacob Carlborg (5/14) May 08 2011 I think I've heard of it but I thought that was before D1 and had been
- bearophile (7/17) May 06 2011 My suggestion is:
- Jacob Carlborg (5/27) May 06 2011 Don't know if it has anything to do with the problem but you have to
- Andrej Mitrovic (3/38) May 06 2011 And char arrays are initialized to 0xFF, which could be another source
Testing out a new binding I knocked up for a C library. One of the functions takes a struct by value. It looks somewhat like this: struct S {} struct Color { float r,g,b,a; } extern C void function(S* s, Color color, int x, int y, in char*) draw_text; Now, there is another function that adjusts color values when making a color. In C, it is sometimes used like so: draw_text(s, map_color(255, 0, 0, 0), 0, 0, "Blarg"); When I'm calling draw_text like this on the D side, my text output is corrupt. I keep getting weird things like ^^P^, but in the appropriate color. It's consistent, no matter what string I pass, but is different for each color value. If I call draw_text like this: auto color = map_color(...); draw_text(s, color, 0, 0, "Blarg"); It works as expected. Has anyone else seen this, or know of a workaround? I'm going to dig through bugzilla later on and see if it's been reported already, but I'm curious if anyone knows of the cause off hand.
May 06 2011
On Fri, 06 May 2011 05:56:17 -0400, Mike Parker <aldacron gmail.com> wrote:Testing out a new binding I knocked up for a C library. One of the functions takes a struct by value. It looks somewhat like this: struct S {} struct Color { float r,g,b,a; } extern C void function(S* s, Color color, int x, int y, in char*) draw_text; Now, there is another function that adjusts color values when making a color. In C, it is sometimes used like so: draw_text(s, map_color(255, 0, 0, 0), 0, 0, "Blarg"); When I'm calling draw_text like this on the D side, my text output is corrupt. I keep getting weird things like ^^P^, but in the appropriate color. It's consistent, no matter what string I pass, but is different for each color value. If I call draw_text like this: auto color = map_color(...); draw_text(s, color, 0, 0, "Blarg"); It works as expected. Has anyone else seen this, or know of a workaround? I'm going to dig through bugzilla later on and see if it's been reported already, but I'm curious if anyone knows of the cause off hand.There are two possible causes I can think of, depending on how draw_text is defined in C. 1. is it truly a function pointer? That is, does the definition look like void (*draw_text)(S* s, ...), or is it just void draw_text(S* s, ...)? 2. It's possible that the extern C (BTW, I thought it had to be extern(C)?) is only applying to the symbol name draw_text and not the function type. D. It should look like this: extern(C) void draw_text(S * s, Color color, int x, int y, in char *); draw text, do: pragma(msg, (typeof(draw_text)).stringof); This hopefully tells you that it's extern(C), but if not, that is likely the problem. If that's not it, I have no idea ;) -Steve
May 06 2011
On 5/6/2011 9:19 PM, Steven Schveighoffer wrote:On Fri, 06 May 2011 05:56:17 -0400, Mike Parker <aldacron gmail.com> wrote:It's a pointer to a function symbol in a DLL. In Derelict, all functions are pointers on the D side, since the shared libraries are loaded manually. I've bound several C libs in the same way and never encountered this before.Testing out a new binding I knocked up for a C library. One of the functions takes a struct by value. It looks somewhat like this: struct S {} struct Color { float r,g,b,a; } extern C void function(S* s, Color color, int x, int y, in char*) draw_text; Now, there is another function that adjusts color values when making a color. In C, it is sometimes used like so: draw_text(s, map_color(255, 0, 0, 0), 0, 0, "Blarg"); When I'm calling draw_text like this on the D side, my text output is corrupt. I keep getting weird things like ^^P^, but in the appropriate color. It's consistent, no matter what string I pass, but is different for each color value. If I call draw_text like this: auto color = map_color(...); draw_text(s, color, 0, 0, "Blarg"); It works as expected. Has anyone else seen this, or know of a workaround? I'm going to dig through bugzilla later on and see if it's been reported already, but I'm curious if anyone knows of the cause off hand.There are two possible causes I can think of, depending on how draw_text is defined in C. 1. is it truly a function pointer? That is, does the definition look like void (*draw_text)(S* s, ...), or is it just void draw_text(S* s, ...)?2. It's possible that the extern C (BTW, I thought it had to be extern(C)?) is only applying to the symbol name draw_text and not the function type.Yeah, that's a typo in my post. It's definitely declared as extern(C) in the source. And I checked with the pragma given below to make sure.in D. It should look like this: extern(C) void draw_text(S * s, Color color, int x, int y, in char *); to draw text, do: pragma(msg, (typeof(draw_text)).stringof); This hopefully tells you that it's extern(C), but if not, that is likely the problem. If that's not it, I have no idea ;)Thanks for the guesses. I don't believe any of the libraries I've bound before now have any functions that take a struct by value. If they have, I haven't had occasion to use them yet. So I wonder if this is an issue with how the compiler handles returning a value struct from a function. Could there be a difference in how it's pushed on to the stack in a D function call versus how it's expected in C? Just grasping.
May 06 2011
On 2011-05-06 11:56, Mike Parker wrote:Testing out a new binding I knocked up for a C library. One of the functions takes a struct by value. It looks somewhat like this: struct S {} struct Color { float r,g,b,a; } extern C void function(S* s, Color color, int x, int y, in char*) draw_text; Now, there is another function that adjusts color values when making a color. In C, it is sometimes used like so: draw_text(s, map_color(255, 0, 0, 0), 0, 0, "Blarg"); When I'm calling draw_text like this on the D side, my text output is corrupt. I keep getting weird things like ^^P^, but in the appropriate color. It's consistent, no matter what string I pass, but is different for each color value. If I call draw_text like this: auto color = map_color(...); draw_text(s, color, 0, 0, "Blarg"); It works as expected. Has anyone else seen this, or know of a workaround? I'm going to dig through bugzilla later on and see if it's been reported already, but I'm curious if anyone knows of the cause off hand.You need to convert the string into a C string; import std.string; auto color = map_color(...); draw_text(s, color, 0, 0, "Blarg".toStringz); -- /Jacob Carlborg
May 06 2011
On Fri, 06 May 2011 09:16:02 -0400, Jacob Carlborg <doob me.com> wrote:On 2011-05-06 11:56, Mike Parker wrote:No, D implicitly casts string literals to zero-terminated const(char)*. That part is fine. -SteveTesting out a new binding I knocked up for a C library. One of the functions takes a struct by value. It looks somewhat like this: struct S {} struct Color { float r,g,b,a; } extern C void function(S* s, Color color, int x, int y, in char*) draw_text; Now, there is another function that adjusts color values when making a color. In C, it is sometimes used like so: draw_text(s, map_color(255, 0, 0, 0), 0, 0, "Blarg"); When I'm calling draw_text like this on the D side, my text output is corrupt. I keep getting weird things like ^^P^, but in the appropriate color. It's consistent, no matter what string I pass, but is different for each color value. If I call draw_text like this: auto color = map_color(...); draw_text(s, color, 0, 0, "Blarg"); It works as expected. Has anyone else seen this, or know of a workaround? I'm going to dig through bugzilla later on and see if it's been reported already, but I'm curious if anyone knows of the cause off hand.You need to convert the string into a C string; import std.string; auto color = map_color(...); draw_text(s, color, 0, 0, "Blarg".toStringz);
May 06 2011
On 5/6/2011 10:23 PM, Steven Schveighoffer wrote:On Fri, 06 May 2011 09:16:02 -0400, Jacob Carlborg <doob me.com> wrote:toStringz was actually the first thing I went for when I got the corrupted output, thinking that maybe literals were no longer null terminated. I can't for the life of me figure out what's different about passing a local struct variable and one that's returned by value from a function call. The only thing I can think of is that the temp returned from the function is somehow corrupting the stack when it's pushed for the function call. But why? I'm hoping someone can shed some light on that aspect.On 2011-05-06 11:56, Mike Parker wrote:No, D implicitly casts string literals to zero-terminated const(char)*. That part is fine.Testing out a new binding I knocked up for a C library. One of the functions takes a struct by value. It looks somewhat like this: struct S {} struct Color { float r,g,b,a; } extern C void function(S* s, Color color, int x, int y, in char*) draw_text; Now, there is another function that adjusts color values when making a color. In C, it is sometimes used like so: draw_text(s, map_color(255, 0, 0, 0), 0, 0, "Blarg"); When I'm calling draw_text like this on the D side, my text output is corrupt. I keep getting weird things like ^^P^, but in the appropriate color. It's consistent, no matter what string I pass, but is different for each color value. If I call draw_text like this: auto color = map_color(...); draw_text(s, color, 0, 0, "Blarg"); It works as expected. Has anyone else seen this, or know of a workaround? I'm going to dig through bugzilla later on and see if it's been reported already, but I'm curious if anyone knows of the cause off hand.You need to convert the string into a C string; import std.string; auto color = map_color(...); draw_text(s, color, 0, 0, "Blarg".toStringz);
May 06 2011
On 2011-05-06 15:23, Steven Schveighoffer wrote:On Fri, 06 May 2011 09:16:02 -0400, Jacob Carlborg <doob me.com> wrote:Since when? -- /Jacob CarlborgOn 2011-05-06 11:56, Mike Parker wrote:No, D implicitly casts string literals to zero-terminated const(char)*. That part is fine. -SteveTesting out a new binding I knocked up for a C library. One of the functions takes a struct by value. It looks somewhat like this: struct S {} struct Color { float r,g,b,a; } extern C void function(S* s, Color color, int x, int y, in char*) draw_text; Now, there is another function that adjusts color values when making a color. In C, it is sometimes used like so: draw_text(s, map_color(255, 0, 0, 0), 0, 0, "Blarg"); When I'm calling draw_text like this on the D side, my text output is corrupt. I keep getting weird things like ^^P^, but in the appropriate color. It's consistent, no matter what string I pass, but is different for each color value. If I call draw_text like this: auto color = map_color(...); draw_text(s, color, 0, 0, "Blarg"); It works as expected. Has anyone else seen this, or know of a workaround? I'm going to dig through bugzilla later on and see if it's been reported already, but I'm curious if anyone knows of the cause off hand.You need to convert the string into a C string; import std.string; auto color = map_color(...); draw_text(s, color, 0, 0, "Blarg".toStringz);
May 06 2011
On 06/05/2011 19:40, Jacob Carlborg wrote:Since const was introduced, before then they implicitly casted to char* instead. And that has been the case since early D1. -- Robert http://octarineparrot.com/No, D implicitly casts string literals to zero-terminated const(char)*. That part is fine. -SteveSince when?
May 06 2011
On 2011-05-06 21:05, Robert Clipsham wrote:On 06/05/2011 19:40, Jacob Carlborg wrote:I think I've heard of it but I thought that was before D1 and had been remove. -- /Jacob CarlborgSince const was introduced, before then they implicitly casted to char* instead. And that has been the case since early D1.No, D implicitly casts string literals to zero-terminated const(char)*. That part is fine. -SteveSince when?
May 08 2011
Mike Parker:Testing out a new binding I knocked up for a C library. One of the functions takes a struct by value. It looks somewhat like this: struct S {} struct Color { float r,g,b,a; } extern C void function(S* s, Color color, int x, int y, in char*) draw_text;My suggestion is: 1) create a test case that shows your program with minimal D code and minimal C code. 2) Create the binary 3) Disassembly it, take a look at the ASM and find the relevant parts, or show them here... Bye, bearophile
May 06 2011
On 2011-05-06 11:56, Mike Parker wrote:Testing out a new binding I knocked up for a C library. One of the functions takes a struct by value. It looks somewhat like this: struct S {} struct Color { float r,g,b,a; } extern C void function(S* s, Color color, int x, int y, in char*) draw_text; Now, there is another function that adjusts color values when making a color. In C, it is sometimes used like so: draw_text(s, map_color(255, 0, 0, 0), 0, 0, "Blarg"); When I'm calling draw_text like this on the D side, my text output is corrupt. I keep getting weird things like ^^P^, but in the appropriate color. It's consistent, no matter what string I pass, but is different for each color value. If I call draw_text like this: auto color = map_color(...); draw_text(s, color, 0, 0, "Blarg"); It works as expected. Has anyone else seen this, or know of a workaround? I'm going to dig through bugzilla later on and see if it's been reported already, but I'm curious if anyone knows of the cause off hand.Don't know if it has anything to do with the problem but you have to watch out with the floats, they are initialized to NaN. -- /Jacob Carlborg
May 06 2011
On 5/6/11, Jacob Carlborg <doob me.com> wrote:On 2011-05-06 11:56, Mike Parker wrote:And char arrays are initialized to 0xFF, which could be another source of problems.Testing out a new binding I knocked up for a C library. One of the functions takes a struct by value. It looks somewhat like this: struct S {} struct Color { float r,g,b,a; } extern C void function(S* s, Color color, int x, int y, in char*) draw_text; Now, there is another function that adjusts color values when making a color. In C, it is sometimes used like so: draw_text(s, map_color(255, 0, 0, 0), 0, 0, "Blarg"); When I'm calling draw_text like this on the D side, my text output is corrupt. I keep getting weird things like ^^P^, but in the appropriate color. It's consistent, no matter what string I pass, but is different for each color value. If I call draw_text like this: auto color = map_color(...); draw_text(s, color, 0, 0, "Blarg"); It works as expected. Has anyone else seen this, or know of a workaround? I'm going to dig through bugzilla later on and see if it's been reported already, but I'm curious if anyone knows of the cause off hand.Don't know if it has anything to do with the problem but you have to watch out with the floats, they are initialized to NaN. -- /Jacob Carlborg
May 06 2011