Public Group

# Std::string to System::String

This topic is 3889 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Alright, so I have been trying to convert and std::string value into a System::String (Which seems far inferior to and std::string anyway, I never know what microsoft is thinking...). I'm using the System::Convert::ToString() function, and passing the string. Now, I've run it, but instead of reading the const char* that std::string::c_str() returns, the crappy CLI reads it as a bool! Seriously, aside from wtf microsoft!? how do I get my string recognized as a const char as opposed to a bool? I just want to convert and use my std::strings from my C++/ISO classes. Is it possible?

##### Share on other sites
It's a poor workman who blames his tools, especially when they're so well documented.

##### Share on other sites
Quote:
 Alright, so I have been trying to convert and std::string value into a System::String (Which seems far inferior to and std::string anyway, I never know what microsoft is thinking...).

Er. Just to be sure, are you actually intending on doing this? Do you know you're working in C++/CLI and are you trying to write interop code?

I ask because very frequently, people end up accidentally creating C++/CLI projects (incorrectly assuming CLI means "command line interface" here) instead of pure C++ ones, and then feeling like Microsoft has "forced" them to abandon standard C++ classes and syntax for (what they assume is) "Microsoft C++" features like System::String, managed reference types (T^ foo and such) and so on.

##### Share on other sites
@ jpetrie
Yeah, I sorta had an idea of what I was getting into, but I didn't know that CLI and ISO were incompatible. I was trying to simplify the building of graphics engine tools (cause windows API seemed so damn complex for what I was doing. I prefer to work with tools of my own creation when possible, so I have build a series of abstractions for directX and windows (also hopefully will ease portability later on) so I wanted to just slide my ISO C++ classes into a windows forms application and leave it. Little did I know...

Ah yes, I know that when programming every error is my own fault. Without exception. However, I like to shift blame, it helps fight depression. In anycase, I am marshaling the strings. However, the problem is that they are standing at an undefined value. The std::string has a value of "purple.png". I know this for a fact, having hard coded it previously (in another project). Now, when I marshal the string and attempt to set the pictureBox1->ImageLocation member with it, my debugger tells me quite clearly that my system::string has an undefined value. (I wonder why microsoft didn't make System::string compatible with std::String).
Here is the code I am using:
void MarshalString ( String ^ s, std::string& os ) {   using namespace Runtime::InteropServices;   const char* chars =       (const char*)(Marshal::StringToHGlobalAnsi(s)).ToPointer();   os = chars;   Marshal::FreeHGlobal(IntPtr((void*)chars));}private: System::Void aquire_Click(System::Object^  sender, System::EventArgs^  e) {			 System::String^ s1;			 this->cx->Text = System::Convert::ToString(objptr->m_cx);			 this->cy->Text = System::Convert::ToString(objptr->m_cy);			 this->h->Text = System::Convert::ToString(objptr->m_h);			 this->w->Text = System::Convert::ToString(objptr->m_w);			 this->sy->Text = System::Convert::ToString(objptr->m_sy);			 this->sx->Text = System::Convert::ToString(objptr->m_sx);			 ToNETstring(s1, objptr->m_animdir.c_str()); //This might actually be the opposite of what I said I am trying to do... this is std-> system			 this->animation->Text = s1;			 ToNETstring(s1 ,objptr->m_dir.c_str());			 this->texture->Text = s1;			 this->current_index=0;			 this->pictureBox1->ImageLocation = this->texture->Text;			 this->pictureBox1->Load();		 }

I blame dot net for it's incompatibility (or at least, it's very roundabout compatibility).

##### Share on other sites
Quote:
 Original post by Plasmarobo(I wonder why microsoft didn't make System::string compatible with std::String).
I'm not sure if that's "wondering" so much as "complaining", but here's the answer anyway: Basing System.String on std::string would be utterly stupid. First of all, std::string is a template-based class, which by itself would make it useless for any framework that wasn't purely C++-targeted. Secondly, System.String is an immutable string type, for various good reasons, which means that the manner in which std::string is implemented would be wasteful and inefficient compared to how System.String is actually implemented. Thirdly, std::string has a rather poor and bloated public interface, dating back to the early days of C++, and so while it is the uncontested standard in C++ there's no reason to infect other languages with it. Fourthly, it wouldn't play well with Unicode strings. Fifthly, many of its public functions rely on an iterator-pair idiom which is fundamentally incompatible with never mind I'm bored of this.

##### Share on other sites
Okay, basically std::string has some design issues that don't fit some (maybe most, maybe not) patterns. But it is still ridiculously easy to use. So I used it. Now, I have a std::string. Or a char* array if you'd rather.
What I need is a system::string that is an exact copy of the std::string instead of an undefined value. Is it possible?

Things I have tried:
Marshaling: Result undefined
Casting: Didn't work, compile error
Char *: Didn't work, compile error
Google: Found some that "work", but for me: Result undefined
This Forum: Some flaming, some complaining on my part, but I still have hope.

##### Share on other sites
Yes. And I already linked you to how to do it. Or, if you prefer, STW.

##### Share on other sites
Alright, so I'm using marshaling. Why is my result undefined?
In my debugger I expand the s1 system string, and it gives me a nice neat <undefined value>
Sorry, I don't mean to sound so hopelessly ignorant, but I am.
At least I am slowly learning here.

What causes a system string to be undefined?

The marshal class ptrtostringansi won't except std::string or std::String::c_str as a valid argument... whats up with that?

##### Share on other sites
Hell if I know. You didn't post ToNETstring, so there's no way to tell what's going wrong. If I had to guess, you're passing a managed pointer in by value and expecting it to act as though it were passed by reference.

##### Share on other sites
Whoops, well, I'll post that here.
Also, how the hell do I get and std::string into and intPtr? Should I just create and intPtr and assign it to &std::string?
void ToNETstring(System::String^ s1, const char* s )	{	s1 = gcnew String( s );	}

The above is not my work.
Here's the code using marshaling:
System::String^ s1;			 this->cx->Text = System::Convert::ToString(objptr->m_cx);			 this->cy->Text = System::Convert::ToString(objptr->m_cy);			 this->h->Text = System::Convert::ToString(objptr->m_h);			 this->w->Text = System::Convert::ToString(objptr->m_w);			 this->sy->Text = System::Convert::ToString(objptr->m_sy);			 this->sx->Text = System::Convert::ToString(objptr->m_sx);			 //ToNETstring(s1, objptr->m_animdir.c_str());			 this->animation->Text = System::Runtime::InteropServices::Marshal::PtrToStringAnsi(&objptr->m_animdir);			 //ToNETstring(s1 ,objptr->m_dir.c_str());			 this->texture->Text = System::Runtime::InteropServices::Marshal::PtrToStringAnsi(&objptr->m_dir);			 this->current_index=0;			 this->pictureBox1->ImageLocation = this->texture->Text;			 				this->pictureBox1->Load();

Heh, thanks for helping me out. I would like to think that under normal circumstances (like understanding the language or API that I am working in) I am rather less dense.

Okay, this supposedly converts std::String to an intPtr, so I can just use this right?
System::IntPtr ptr(static_cast<System::IntPtr>(static_cast<void*>(const_cast<char*>(ss.c_str()))));

[edit2]
Holy crap! That did it. Thanks guys! Hopefully I will never have to use CLS or microsoft code again, but if I do, I'll avoid a head ache and just choose one, instead of trying to mix.

• 10
• 17
• 9
• 14
• 41