Sign in to follow this  

Std::string to System::String

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

If you intended to correct an error in the post then please contact us.

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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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?
[edit]
The marshal class ptrtostringansi won't except std::string or std::String::c_str as a valid argument... whats up with that?

Share this post


Link to post
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 this post


Link to post
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.
[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.

Share this post


Link to post
Share on other sites
PtrToStringANSI takes the address of a char array, not the address of a std::string. Pass in the result of c_str.

Share this post


Link to post
Share on other sites
Quote:

but I didn't know that CLI and ISO were incompatible.

They're compatible. They're not interchangeable.

Quote:

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...

Working in C++/CLI isn't very pretty -- I'd prefer to work in C# for the GUI, and talk to a C++/CLI wrapper around the C++ engine. This won't solve your problems, of course, but it will make some things later on a bit easier.

Quote:

Hopefully I will never have to use CLS or microsoft code again, but if I do,


Here's the thing. You're doing marshalling and interop between an unmanaged environment (C++) and a managed one (the CLI). This is very hard to do correctly, and you should really be grateful for the wonderful tools C++/CLI provides you for doing this rather than having to roll your own, which due to the confluence of complexities involved is likely to be nastier than most C++-only memory-management screwdowns the average programmer has had to experience and debug.

The multitude of different ways to marshal data between environments reflects the complexity of the operations you're trying to do; it's not as simple and clear-cut as converting from one string representation to another. Even if that's what it looks like you're doing on the surface.

Share this post


Link to post
Share on other sites

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

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this