Jump to page: 1 2
Thread overview
Help passing D strings to C libs
Mar 14, 2011
Gene P. Cross
Mar 14, 2011
Andrej Mitrovic
Mar 14, 2011
Andrej Mitrovic
Mar 14, 2011
Gene P. Cross
Mar 14, 2011
Jonathan M Davis
Mar 14, 2011
Gene P. Cross
Mar 14, 2011
Daniel Green
Mar 14, 2011
Gene P. Cross
Mar 14, 2011
Gene P. Cross
Mar 14, 2011
Daniel Green
Mar 14, 2011
Gene P. Cross
Mar 14, 2011
Jonathan M Davis
Mar 14, 2011
Daniel Green
Mar 14, 2011
Jonathan M Davis
Mar 14, 2011
Trass3r
Mar 14, 2011
Jonathan M Davis
March 14, 2011
Hi, I'm fairly new to D and I'm writing a Space Invaders clone to get myself acquainted with the language.

I'm having trouble passing D strings (char[]) to SDL, in particular
SDL_LoadBMP(), I keep receiving a segfault.

Heres the code:

void setImg(string path) {
    // concat null terminating char to string and cast to c type string when
    // passing to SDL_LoadBMP()
    path ~= "\0";
    image = SDL_LoadBMP( cast(char*)path );
}

and the value of path is "./resources/cannon.bmp"

I'm using SDL 1.2.14 and DMD 1.067 on Ubuntu 10.10

If someone could tell me what I'm doing wrong it would be greatly appreciated.

March 14, 2011
Use toStringz from std.string, ala:
SDL_LoadBMP(toStringz(path));

Do not embed nulls before calling toStringz, so remove 'path ~= "\0";'
March 14, 2011
Wait, actually I'm not sure if there's toStringz for D1, it is there for D2. Try it out, I guess.
March 14, 2011
toStringz is in D1 but still no luck, I still get the same error

Thanks for the suggestion though
March 14, 2011
On Sunday 13 March 2011 21:32:49 Gene P. Cross wrote:
> Hi, I'm fairly new to D and I'm writing a Space Invaders clone to get myself acquainted with the language.
> 
> I'm having trouble passing D strings (char[]) to SDL, in particular
> SDL_LoadBMP(), I keep receiving a segfault.
> 
> Heres the code:
> 
> void setImg(string path) {
>     // concat null terminating char to string and cast to c type string
> when // passing to SDL_LoadBMP()
>     path ~= "\0";
>     image = SDL_LoadBMP( cast(char*)path );
> }
> 
> and the value of path is "./resources/cannon.bmp"
> 
> I'm using SDL 1.2.14 and DMD 1.067 on Ubuntu 10.10
> 
> If someone could tell me what I'm doing wrong it would be greatly appreciated.

I don't use D1, so I don't know all of the ins and outs, but you're going to have to make sure that you put a "\0" at the end of the string so that it's properly null-terminated (which you appear to be doing), and you should be passing the string's ptr property to the function, not casting the string to char*.

If you were dealing with D2, you'd also have to worry about not passing a string (as opposed to a char[]) to a C function if there's _any_ chance that it would alter it, since string in D2 is immutable(char)[], but that's not the case in D1, so that shouldn't be a problem with what you're doing.

- Jonathan M Davis
March 14, 2011
I've amended the source to pass the strings pointer (path.ptr) after adding a null but the problem still persists.

I lost for what it could be and I'm certain this is where the problem is, because if I remove the method call, the program runs fine.

I've noticed that calling SDL_LoadBMP and passing a string literal seems to work, instead of a string variable. I might load all the images independently into an array and have each object reference that array, instead of every object loading its own.
March 14, 2011
On 3/14/2011 1:38 AM, Gene P. Cross wrote:
> I've amended the source to pass the strings pointer (path.ptr) after adding a null
> but the problem still persists.
>
> I lost for what it could be and I'm certain this is where the problem is, because
> if I remove the method call, the program runs fine.
>
> I've noticed that calling SDL_LoadBMP and passing a string literal seems to work,
> instead of a string variable. I might load all the images independently into an
> array and have each object reference that array, instead of every object loading
> its own.

It sounds like a bug with version of D your using.  I make heavy use of toStringz with a lua wrapper I have.  If you can debug your program, try doing something like this.

char* ptr = toStringz(path);
SDL_LoadBMP(ptr);

and inspect ptr before the call to SDL_LoadBMP.  I would also replace string with char[].  To be sure that string isn't really wchar[] or dchar[].  Although, I imagine the compiler would catch that.
March 14, 2011
On Sunday 13 March 2011 22:38:49 Gene P. Cross wrote:
> I've amended the source to pass the strings pointer (path.ptr) after adding a null but the problem still persists.
> 
> I lost for what it could be and I'm certain this is where the problem is, because if I remove the method call, the program runs fine.
> 
> I've noticed that calling SDL_LoadBMP and passing a string literal seems to work, instead of a string variable. I might load all the images independently into an array and have each object reference that array, instead of every object loading its own.

In D2 (and I assume D1, but I don't know), string literals all have "\0" one past their end, so you can safely pass them to C functions. Other strings don't have them, so you have to append the "\0". Other than that, I don't know why there would be any difference between passing a string literal and a regular string. Perhaps something else in your code is altering the string later (which it wouldn't do if you just passed a literal) and _that_ is screwing it up. I don't know. For the most part, there shouldn't be much difference between dealing with string literals and dealing with normal strings.

- Jonathan M Davis
March 14, 2011
-Daniel
I tried what you said:

char* ptr = toStringz(path);
SDL_LoadBMP(ptr);

and made a check to see if the pointer is null, which it isn't, but I'm unable to inspect is value, I haven't a debugger at the moment, could you recommend one ?

I also made the string a char[] and tested to see if that made a difference.

I think it may be something to do with SDL itself. I tried calling another function, SDL_GetTicks(), and that's causing problems as well.


-Jonathan
I read the docs earlier and found the same thing about literals being null
terminated but not regular strings,
which explains why they work.
Double check after double check, I am also certain that no other code is messing
with it and changing values.
March 14, 2011
I found the problem.

I've set up my 'main' file to act on various game states and because my load state is physically below the running state (where the problems were occuring), even though they were getting called first, the program starts in the loading state, dmd wasn't having it. I tried moving the load state above the rest, and it works fine. So sorry to have wasted everybody's time with such a simple and stupid mistake. Thankyou for all your help.
« First   ‹ Prev
1 2