Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / Managed C++ / September 2007

Tip: Looking for answers? Try searching our database.

String::Format problem

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Derek Kuliński / takeda - 30 Aug 2007 17:28 GMT
I spent many hours on this, googling around and experimenting, and still
nothing.

I wrote an umanaged program (actually various classes), while I was
developing them I used command line to test it.
Now, I decided to make GUI for it, so I created new project: "Windows Forms
Application (.NET)" (I was trying to use something that's not managed (e.g.
MFC, but I learned quickly that I don't actually know how to use MFC :)
In .NET I was able to quickly create the GUI that looked as I wanted it too
look.

Now my problem is really silly. While I figured out how to convert
System::String to for example std::string, and looks like the other way
around is actually easy, I can't for a love of God make String::Format do
what I want.
Even the examples from MSDN doesn't work when I copy&paste them verbatim!
Here is an example:
http://msdn2.microsoft.com/en-us/library/fht0f5be.aspx

In a simple program that has just textbox, button and label, the following
code works:
label1->Text = String::Format("Hello, {0}", textBox1->Text);

But this, doesn't want to:
label1->Text = String::Format("Hello, {0}", 10);

My goal is basically do something like this:
unsigned short int pc = 8000;
label1->Text = String::Format("Address: {0,4:X}", pc);

Anyone has idea what I'm doing wrong?

I have also an unrelated question: If I have a managed class (for the
form), and I define inside a pointer to an unmanaged class, is that a good
practice? Right now it appears to work fine, but before I had an exception
that the pointer is null (even though I did new on the form's load, and
pointer was used after selecting an option from a menu). I have no idea how
I even fixed it.

Thanks for help.
Signature

ダレック

Ben Voigt [C++ MVP] - 30 Aug 2007 20:06 GMT
> My goal is basically do something like this:
> unsigned short int pc = 8000;
> label1->Text = String::Format("Address: {0,4:X}", pc);

Would this be sufficient for you?
label1->Text = "Address: " + pc.ToString("X4");

> Anyone has idea what I'm doing wrong?
>
[quoted text clipped - 5 lines]
> how
> I even fixed it.

That is the right way to use native classes from managed code.  Often, you
create a managed class to wrap each native object, and its only
responsibility is taking care of that one native pointer.

> Thanks for help.
Derek Kuliński / takeda - 30 Aug 2007 21:15 GMT
>> My goal is basically do something like this:
>> unsigned short int pc = 8000;
>> label1->Text = String::Format("Address: {0,4:X}", pc);
>
> Would this be sufficient for you?
> label1->Text = "Address: " + pc.ToString("X4");

I had no idea I could use .ToString() on non objects...
But unfortunately, I'm getting now:
e:\Documents and Settings\takeda\My Documents\Visual Studio
Projects\test\Form1.h(98) : error C2110: '+' : cannot add two pointers

Also, this solution would solve the current problem I'm having, but I'm
afraid that I'll come with another related question, that .ToString() might
not solve for me...

>> Anyone has idea what I'm doing wrong?
>> I have also an unrelated question: If I have a managed class (for the
[quoted text clipped - 7 lines]
> create a managed class to wrap each native object, and its only
> responsibility is taking care of that one native pointer.

That's good. Any recommendation. where I can read more about wrapping
unmanaged classes inside of managed ones?

Signature

ダレック

Ben Voigt [C++ MVP] - 31 Aug 2007 00:16 GMT
>>> My goal is basically do something like this:
>>> unsigned short int pc = 8000;
[quoted text clipped - 4 lines]
>
> I had no idea I could use .ToString() on non objects...

All basic types in C++/CLI have a dual citizenship, they are a native
non-object as well as a .NET value type.  Note that this doesn't include
strings, although a string literal can be treated as either a char* or
System::String, variables don't convert back and forth.

> But unfortunately, I'm getting now:
> e:\Documents and Settings\takeda\My Documents\Visual Studio
> Projects\test\Form1.h(98) : error C2110: '+' : cannot add two pointers

one of these should work:

label1->Text = gcnew String("Address: ") + pc.ToString("X4");

label1->Text = String::Concat("Address: ", pc.ToString("X4"));

> Also, this solution would solve the current problem I'm having, but I'm
> afraid that I'll come with another related question, that .ToString()
> might
> not solve for me...

I think your format string was wrong.  looking at the documentation, I think
it should be:
label1->Text = String::Format("Address: {0,X4}", pc);

if you need the flexibility that String::Format gives (it's useful for
localization, when different languages might want to show the values in a
different order).  If you don't need the reordering, explicit ToString will
be much faster than String::Format.  In fact, this is quite possibly faster
than what you had:
label1->Text = String::Format("Address: {0}", pc.ToString("X4"));

>>> Anyone has idea what I'm doing wrong?
>>> I have also an unrelated question: If I have a managed class (for the
[quoted text clipped - 13 lines]
> That's good. Any recommendation. where I can read more about wrapping
> unmanaged classes inside of managed ones?

For the pure .NET interop (p/invoke) way (needed for verifiable code), use
.NET Reflector to take a look at SafeHandle.

For the C++ interop way (faster, easier), google for C++/CLI wrapper, there
are some promising results including several on codeproject.
Derek Kuliński / takeda - 31 Aug 2007 02:30 GMT
>>> Would this be sufficient for you?
>>> label1->Text = "Address: " + pc.ToString("X4");
>> I had no idea I could use .ToString() on non objects...
> All basic types in C++/CLI have a dual citizenship, they are a native
> non-object as well as a .NET value type.

So it is just .NET thing, and won't work with other compilers I assume.

> Note that this doesn't include
> strings, although a string literal can be treated as either a char* or
> System::String, variables don't convert back and forth.

I noticed that I can't convert them back and forth, but I learned about
Marshal::StringToHGlobalAnsi which seems to do the job.

>> But unfortunately, I'm getting now:
>> e:\Documents and Settings\takeda\My Documents\Visual Studio
>> Projects\test\Form1.h(98) : error C2110: '+' : cannot add two pointers
> one of these should work:
> label1->Text = gcnew String("Address: ") + pc.ToString("X4");
> label1->Text = String::Concat("Address: ", pc.ToString("X4"));

The second one seems to be working flawlessly.
The first one tells me that gcnew is undeclared:
e:\Documents and Settings\takeda\My Documents\Visual Studio
Projects\test\Form1.h(99) : error C2065: 'gcnew' : undeclared identifier
e:\Documents and Settings\takeda\My Documents\Visual Studio
Projects\test\Form1.h(99) : error C2146: syntax error : missing ';' before
identifier 'String'
e:\Documents and Settings\takeda\My Documents\Visual Studio
Projects\test\Form1.h(99) : error C3604: 'System::String': can only create
a __gc type object on the __gc heap
       __gc types can not be created on the stack

Maybe there's some option enabled in my VC++ (it is from VS 2003), but
which option is responsible for that?
There's comman line arguments for the compiler:
/Od /AI "E:\Documents and Settings\takeda\My Documents\Visual Studio
Projects\test\Debug" /D "WIN32" /D "_DEBUG" /D "_MBCS" /FD /EHsc /MTd /GS
/Yu"stdafx.h" /Fp"Debug/test.pch" /Fo"Debug/" /Fd"Debug/vc70.pdb" /W3
/nologo /c /Zi /clr /TP /FU
"C:\WINNT\Microsoft.NET\Framework\v1.1.4322\mscorlib.dll" /FU
"C:\WINNT\Microsoft.NET\Framework\v1.1.4322\System.dll" /FU
"C:\WINNT\Microsoft.NET\Framework\v1.1.4322\System.Data.dll" /FU
"C:\WINNT\Microsoft.NET\Framework\v1.1.4322\System.Drawing.dll" /FU
"C:\WINNT\Microsoft.NET\Framework\v1.1.4322\System.Windows.Forms.dll" /FU
"C:\WINNT\Microsoft.NET\Framework\v1.1.4322\System.XML.dll"

and linker:
/OUT:"E:\Documents and Settings\takeda\My Documents\Visual Studio
Projects\test\Debug\test.exe" /INCREMENTAL /NOLOGO /DEBUG /ASSEMBLYDEBUG
/PDB:"E:\Documents and Settings\takeda\My Documents\Visual Studio
Projects\test\Debug/test.pdb" /SUBSYSTEM:WINDOWS /FIXED:No   kernel32.lib
user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib
ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib

>> Also, this solution would solve the current problem I'm having, but I'm
>> afraid that I'll come with another related question, that .ToString()
[quoted text clipped - 10 lines]
> than what you had:
> label1->Text = String::Format("Address: {0}", pc.ToString("X4"));

I think I initially wrote it just like you showed me.
It didn't worked, and neither did this:
label1->Text = String::Format("Hello, {0}", 10);

>> That's good. Any recommendation. where I can read more about wrapping
>> unmanaged classes inside of managed ones?
> For the pure .NET interop (p/invoke) way (needed for verifiable code), use
> .NET Reflector to take a look at SafeHandle.
> For the C++ interop way (faster, easier), google for C++/CLI wrapper, there
> are some promising results including several on codeproject.

I will, thank you.

While I still have questions, at lest I can work with String::Concat and
.ToString() around that.
I'm really wondering what's wrong with my C++ compiler. Even examples on
MSDN webpage didn't work.

Signature

ダレック
takeda@IRCnet.EFnet, ICQ# 15827691, YahooIM: takeda64
http://ircwiki.takeda.tk - strona wiki poświęcona IRC

Ben Voigt [C++ MVP] - 04 Sep 2007 17:13 GMT
[snip]
> Maybe there's some option enabled in my VC++ (it is from VS 2003), but
> which option is responsible for that?

[snip]
> I'm really wondering what's wrong with my C++ compiler. Even examples on
> MSDN webpage didn't work.

You need an upgrade to VC 2005, even Express Edition will work.  Managed
Extensions for C++ that came with VC 2003 were so full of problems that
Microsoft started over in VC 2005, giving us the C++/CLI language.
Derek Kuliński / takeda - 06 Sep 2007 08:05 GMT
> You need an upgrade to VC 2005, even Express Edition will work.  Managed
> Extensions for C++ that came with VC 2003 were so full of problems that
> Microsoft started over in VC 2005, giving us the C++/CLI language.

Actually one of the readers here (I don't know if he wants me to mention
his name since he answered privately) pointed me to use a __box() around
basic types like integers etc. which seems to do the thing. I can put char*
in String() and it seems to solve most of the problems.
He also recommended me to switch to VS 2005, and I'll try it as soon as I
can.

Anyway, thank you Ben for troubleshooting the problem, I really appreciate
that you tried to help.
I have another question about creating virtual listbox, but I'll create
another thread for it, since it is unrelated.

Signature

ダレック


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.