www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Char * character and string

reply "Chris Pons" <cmpons gmail.com> writes:
Hello,
I am trying to work with SDL and one of their functions takes a 
char * file as a function a parameter. However, i'm running into 
trouble how to actually set this variable in my constructor.

I am getting a problem where if I use a pointer to a char and set 
it as "test.bmp" I get an error stating "cannot implicitly 
convert expression (file) of type string to char*. After that I 
decided to try to set file to 'test.bmp' instead, and in that 
case I get: "Unterminated character constant" . Although I am 
familiar with what this error is referring to, I do not know how 
to add a terminator in D.

This is the function that I intend to use the filename in:
**Note the function LoadBMP is the one that REQUIRES a pointer to 
a char
--------------------------------------
	SDL_Surface * Load(char * file)
	{
		SDL_Surface * Temp = null;

		if((Temp = SDL_LoadBMP(file)) == null)
			return null;

		Surface = SDLDisplayFormat(Temp);

		SDL_FreeSurface(Temp);

		return Surface;
	}
----------------------------------------

This is the constructor that is giving me the error:
----------------------------------------------------------
	char * file;
	
	this()
	{
		this.filename = "test.bmp";
	}
-------------------------------------------------------------
Mar 01 2012
next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, March 02, 2012 05:51:14 Chris Pons wrote:
 Hello,
 I am trying to work with SDL and one of their functions takes a
 char * file as a function a parameter. However, i'm running into
 trouble how to actually set this variable in my constructor.
 
 I am getting a problem where if I use a pointer to a char and set
 it as "test.bmp" I get an error stating "cannot implicitly
 convert expression (file) of type string to char*. After that I
 decided to try to set file to 'test.bmp' instead, and in that
 case I get: "Unterminated character constant" . Although I am
 familiar with what this error is referring to, I do not know how
 to add a terminator in D.
 
 This is the function that I intend to use the filename in:
 **Note the function LoadBMP is the one that REQUIRES a pointer to
 a char
 --------------------------------------
 	SDL_Surface * Load(char * file)
 	{
 		SDL_Surface * Temp = null;
 
 		if((Temp = SDL_LoadBMP(file)) == null)
 			return null;
 
 		Surface = SDLDisplayFormat(Temp);
 
 		SDL_FreeSurface(Temp);
 
 		return Surface;
 	}
 ----------------------------------------
 
 This is the constructor that is giving me the error:
 ----------------------------------------------------------
 	char * file;
 
 	this()
 	{
 		this.filename = "test.bmp";
 	}
 -------------------------------------------------------------

Use std.string.toStringz (or std.utf.toUTFz if immutable(char)* doesn't cut it). Regardless, be careful of passing char* to C code. Even if the C code keeps the pointer, it won't stop the GC from collecting it. The D code needs to have reference to it of some kind (though a pointer in your struct as you appeart to be doing should be plenty as long as an instance of the struct remains in the D code - as opposed to passing it to the C code and then not having it in the D code anymore, which would be no better than just passing the char* to the C code without keeping a reference to it). - Jonathan M Davis
Mar 01 2012
prev sibling next sibling parent "Chris Pons" <cmpons gmail.com> writes:
Thank you for the reply. However, I've run into another problem.

I changed:

-----------

char * file;

this()
{
this.filename = "test.bmp";
}

---------------

To:

----------------

char * file

this()
{
this.filename = toStringz("test.bmp");
}

-----------------------

I am getting this error:

Error	1	Error: cannot implicitly convert expression 
(toStringz("test.bmp")) of type immutable(char)* to 
char*	D:\Documents\Projects\Test\Test\DPBall.d	10	

Instead I tried toUTFz, which I used like this:

--------------------------

	char * filename;
	
	this()
	{
		this.filename = toUTFz("test.bmp");
	}

--------------------------

I get these errors:

Error	1	Error: template std.utf.toUTFz(P,S) if (isSomeString!(S) 
&& isPointer!(P) && isSomeChar!(typeof(*P.init)) && 
is(Unqual!(typeof(*P.init)) == Unqual!(ElementEncodingType!(S))) 
&& is(immutable(Unqual!(ElementEncodingType!(S))) == 
ElementEncodingType!(S))) does not match any function template 
declaration	D:\Documents\Projects\Test\Test\DPBall.d	11	

Error	2	Error: template std.utf.toUTFz(P,S) if (isSomeString!(S) 
&& isPointer!(P) && isSomeChar!(typeof(*P.init)) && 
is(Unqual!(typeof(*P.init)) == Unqual!(ElementEncodingType!(S))) 
&& is(immutable(Unqual!(ElementEncodingType!(S))) == 
ElementEncodingType!(S))) cannot deduce template function from 
argument types 
!()(string)	D:\Documents\Projects\Test\Test\DPBall.d	11	


Am I using these functions incorrectly?
Mar 01 2012
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, March 02, 2012 06:22:41 Chris Pons wrote:
 Thank you for the reply. However, I've run into another problem.
 
 I changed:
 
 -----------
 
 char * file;
 
 this()
 {
 this.filename = "test.bmp";
 }
 
 ---------------
 
 To:
 
 ----------------
 
 char * file
 
 this()
 {
 this.filename = toStringz("test.bmp");
 }
 
 -----------------------
 
 I am getting this error:
 
 Error	1	Error: cannot implicitly convert expression
 (toStringz("test.bmp")) of type immutable(char)* to
 char*	D:\Documents\Projects\Test\Test\DPBall.d	10
 
 Instead I tried toUTFz, which I used like this:
 
 --------------------------
 
 	char * filename;
 
 	this()
 	{
 		this.filename = toUTFz("test.bmp");
 	}
 
 --------------------------
 
 I get these errors:
 
 Error	1	Error: template std.utf.toUTFz(P,S) if (isSomeString!(S)
 && isPointer!(P) && isSomeChar!(typeof(*P.init)) &&
 is(Unqual!(typeof(*P.init)) == Unqual!(ElementEncodingType!(S)))
 && is(immutable(Unqual!(ElementEncodingType!(S))) ==
 ElementEncodingType!(S))) does not match any function template
 declaration	D:\Documents\Projects\Test\Test\DPBall.d	11
 
 Error	2	Error: template std.utf.toUTFz(P,S) if (isSomeString!(S)
 && isPointer!(P) && isSomeChar!(typeof(*P.init)) &&
 is(Unqual!(typeof(*P.init)) == Unqual!(ElementEncodingType!(S)))
 && is(immutable(Unqual!(ElementEncodingType!(S))) ==
 ElementEncodingType!(S))) cannot deduce template function from
 argument types
 !()(string)	D:\Documents\Projects\Test\Test\DPBall.d	11
 
 
 Am I using these functions incorrectly?

toStringz returns an immutable(char)*, so you can assign it to a const(char)* or an immutable(char)* but not a char*. If you want to assign to a char*, then you need to use toUTFz, which you are most definitely using incorrectly. The documentation gives several examples on how to use it correctly, but if what you want is a char*, then you'd do this.filename = toUTFz!(char*)("test.bmp"); toUTFZ is a templated function which requires that you give it the type that you want to convert to. You were trying to call it without giving the type. - Jonathan M Davis
Mar 01 2012
prev sibling next sibling parent "Chris Pons" <cmpons gmail.com> writes:
Ok, got it all sorted. Thank you for the guidance.
Mar 01 2012
prev sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
SDL_LoadBMP is declared as:
SDL_Surface *SDL_LoadBMP(const char *file);
http://www.libsdl.org/cgi/docwiki.cgi/SDL_LoadBMP

So you don't need a mutable char*. I'd recommend using Derelict since
it already has all these prototypes declared properly.
Mar 02 2012