Std::string to System::String

Started by
10 comments, last by jpetrie 16 years, 6 months ago
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?
___________________________________________________Optimists see the glass as Half FullPessimists See the glass as Half EmptyEngineers See the glass as Twice as big as it needs to be
Advertisement
It's a poor workman who blames his tools, especially when they're so well documented.
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.
@ 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).
___________________________________________________Optimists see the glass as Half FullPessimists See the glass as Half EmptyEngineers See the glass as Twice as big as it needs to be
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.
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.
___________________________________________________Optimists see the glass as Half FullPessimists See the glass as Half EmptyEngineers See the glass as Twice as big as it needs to be
Yes. And I already linked you to how to do it. Or, if you prefer, STW.
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?
[edit]
The marshal class ptrtostringansi won't except std::string or std::String::c_str as a valid argument... whats up with that?
___________________________________________________Optimists see the glass as Half FullPessimists See the glass as Half EmptyEngineers See the glass as Twice as big as it needs to be
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.
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.
[edit]
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.
___________________________________________________Optimists see the glass as Half FullPessimists See the glass as Half EmptyEngineers See the glass as Twice as big as it needs to be

This topic is closed to new replies.

Advertisement