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++ / June 2005

Tip: Looking for answers? Try searching our database.

Forcing value to bool (performance warning)

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Howard Kaikow - 01 Jun 2005 22:52 GMT
In the code below, ALL the lines that start with PPTfile << are getting the
following error at build time.

"//i:\C++\C++Code\FileOperations\Form1.h(127) : warning C4800:
'System::String __gc *' : forcing value to bool 'true' or 'false'
(performance warning)"

I get the following output, which is obviously wrong:

    Process ID              =     0x1
    ref count (c)           =     0x1
    Thread Count            =     1
    parent process ID       =     0x1
    Priority Base           =     1
    Process ID              =     0x1
    ref count (c)           =     0x1
    Thread Count            =     1
    Process ID              =     0x1
    Priority Base           =     1
1
1
1
1
1
-------------------------------------------------
DWORD x = 23;
LONG aa = 16;

String *buf;
ofstream PPTfile("PPT.txt", ios::out);
PPTfile << " Process ID = 0x" << x.ToString("X8") << endl;
PPTfile << " ref count (c) = 0x" << x.ToString("X4") << endl;
PPTfile << " Thread Count = " << x.ToString() << endl;
PPTfile << " parent process ID = 0x" << x.ToString("X8") << endl;
PPTfile << " Priority Base = " << aa.ToString() << endl;

buf = x.ToString("X8");
PPTfile << " Process ID = 0x" << buf << endl;
buf = x.ToString("X4");
PPTfile << " ref count (c) = 0x" << buf << endl;
buf = x.ToString();
PPTfile << " Thread Count = " << buf << endl;
buf = x.ToString("X8");
PPTfile << " Process ID = 0x" << buf << endl;
buf = aa.ToString();
PPTfile << " Priority Base = " << buf << endl;

buf = String::Concat(S" Process ID = 0x", x.ToString("X8"));
PPTfile << buf << endl;
buf = String::Concat(S" ref count (c) = 0x", x.ToString("X4"));
PPTfile << buf << endl;
buf=String::Concat(S" Thread Count = ", x.ToString());
PPTfile << buf << endl;
buf=String::Concat(S" parent process ID = 0x", x.ToString("X8"));
PPTfile << buf << endl;
buf =String::Concat(S" Priority Base = ", aa.ToString());
PPTfile << buf << endl;
PPTfile.close();
Tamas Demjen - 01 Jun 2005 23:31 GMT
> In the code below, ALL the lines that start with PPTfile << are getting the
> following error at build time.
[quoted text clipped - 4 lines]
>
> I get the following output, which is obviously wrong:

ToString returns a .NET object handle, which native C++ can't handle,
and therefore it tries to convert it implicitly to bool. Thus the
warning. You have to use the following function (as an example) to
convert managed strings to unmanaged ones:

std::wstring ToUnmanagedString(System::String* str)
{
  const wchar_t __pin* c_str = PtrToStringChars(str);
  return std::wstring(c_str);
}

In addition, you shouldn't use endl, you should use "\n" instead. endl
flushes the stream, which is a serious performance penalty.

Tom
Howard Kaikow - 02 Jun 2005 00:02 GMT
Thanx.

Signature

http://www.standards.com/; See Howard Kaikow's web site.

> > In the code below, ALL the lines that start with PPTfile << are getting the
> > following error at build time.
[quoted text clipped - 20 lines]
>
> Tom
Howard Kaikow - 02 Jun 2005 00:10 GMT
> ToString returns a .NET object handle, which native C++ can't handle,
> and therefore it tries to convert it implicitly to bool. Thus the
[quoted text clipped - 6 lines]
>    return std::wstring(c_str);
> }

Using the above, I got the error:

i:\C++\C++Code\FileOperations\Form1.h(101): error C2230: 'ToUnmanagedString'
: a member function of a managed class cannot return a non-managed class or
struct 'std::basic_string<_Elem,_Traits,_Ax>' unless it is an aggregate
       with
       [
           _Elem=wchar_t,
           _Traits=std::char_traits<wchar_t>,
           _Ax=std::allocator<wchar_t>
       ]

What does that mean?
Tom Widmer - 02 Jun 2005 10:20 GMT
>>ToString returns a .NET object handle, which native C++ can't handle,
>>and therefore it tries to convert it implicitly to bool. Thus the
[quoted text clipped - 20 lines]
>
> What does that mean?

The supplied function should not be a member function - make it a global
or namespace scope function.

Tom
Howard Kaikow - 02 Jun 2005 13:03 GMT
> The supplied function should not be a member function - make it a global
> or namespace scope function.

Thanx.

Now, I'm getting the error

i:\C++\C++Code\FileOperations\Form1.h(162): error C2679: binary '<<' : no
operator found which takes a right-hand operand of type 'std::wstring' (or
there is no acceptable conversion)

in the following code:

DWORD x = 23;
String *buf;
ofstream PPTfile("PPT.txt", ios::out);

buf = x.ToString("X8");
PPTfile << " Process ID = 0x" << ToUnmanagedString(buf)<< "\n";

buf = String::Concat(S" Process ID = 0x", x.ToString("X8"));
PPTfile << ToUnmanagedString(buf) << "\n";

PPTfile.close();

I included the following in stdafx,h

#include <vcclr.h>

and I included the folowing  at the top of the namespace, right after
using namespace System::Drawing;

std::wstring ToUnmanagedString(System::String* str)
{
const wchar_t __pin* c_str = PtrToStringChars(str);
return std::wstring(c_str);
//return std::wstring((wchar_t __pin*) PtrToStringChars(str));
}
Howard Kaikow - 02 Jun 2005 14:33 GMT
I stumbled upon MSFT KB artice 311259, which suggests 3 solutions, including
the one discussed in this thread.
Alas, none of the 3 solutions appear to solve the problem.

The solutions listed are:

PtrToStringChars, as discussed in this thread.
StringToHGlobalAnsi
CString
Carl Daniel [VC++ MVP] - 02 Jun 2005 15:29 GMT
>> The supplied function should not be a member function - make it a
>> global or namespace scope function.
[quoted text clipped - 6 lines]
> : no operator found which takes a right-hand operand of type
> 'std::wstring' (or there is no acceptable conversion)

You're using a wide-character string (std::wstring) with a narrow-character
stream (std::ofstream).  Unfortunately, that doesn't work.

What you really want is to use a wide-character stream (std::wofstream) with
a narrowing facet (assuming you want ASCII/ANSI text in your outpout file
and not Unicode).  Unfortunately, VC++ does not supply a suitable facet
(although the Dinkumware Unabridged library does include one).

What you can do instead is use the .NET framework to do the narrowing
conversion for you:

<untested code>
std::string ToUnmanagedNarrowString(System::String* str)
{
   HGLOBAL hg =
(HGLOBAL)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(str);
   const char* pc = static_cast<const char*>GlobalLock(hg);
   std::string ret(pc,pc+str->get_Length());
   GlobalFree(hg);
   return ret;
}
</untested code>

Note that if Unicode output is acceptable (for example, that ofstream
actually goes to the console), simply changing your ofstream to a wofstream
should be sufficient.

-cd
Howard Kaikow - 02 Jun 2005 15:45 GMT
> You're using a wide-character string (std::wstring) with a narrow-character
> stream (std::ofstream).  Unfortunately, that doesn't work.
[quoted text clipped - 11 lines]
> {
>     HGLOBAL hg =

(HGLOBAL)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(str)
;
>     const char* pc = static_cast<const char*>GlobalLock(hg);
>     std::string ret(pc,pc+str->get_Length());
[quoted text clipped - 6 lines]
> actually goes to the console), simply changing your ofstream to a wofstream
> should be sufficient.

I an writing to a file.

I already display the info in a listbox, I'm just trying to get the stuff
from the listbox into a file, so I can print the file.
Perhaps there's a better way to do that?
Carl Daniel [VC++ MVP] - 02 Jun 2005 15:51 GMT
> "Carl Daniel [VC++ MVP]"
>> Note that if Unicode output is acceptable (for example, that ofstream
[quoted text clipped - 7 lines]
> stuff from the listbox into a file, so I can print the file.
> Perhaps there's a better way to do that?

No, not really.  If you're using .NET for your UI (and hence Unicode) and
youi want to write out a narrow-character file, then you have to explicitly
do the narrowing conversion somewhere.

-cd
Howard Kaikow - 02 Jun 2005 16:20 GMT
> No, not really.  If you're using .NET for your UI (and hence Unicode) and
> youi want to write out a narrow-character file, then you have to explicitly
> do the narrowing conversion somewhere.

I have no problem using the same expressions when adding to a LIstBox
control.
So, I expect that I should byte the bullet and  use the System::IO
namespace.
Carl Daniel [VC++ MVP] - 02 Jun 2005 15:51 GMT
> <untested code>
> std::string ToUnmanagedNarrowString(System::String* str)
> {
>    HGLOBAL hg =
> (HGLOBAL)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(str);
>    const char* pc = static_cast<const char*>GlobalLock(hg);

    const char* pc = static_cast<const char*>(GlobalLock(hg));

>    std::string ret(pc,pc+str->get_Length());
>    GlobalFree(hg);
>    return ret;
> }
> </untested code>

-cd
Howard Kaikow - 02 Jun 2005 19:42 GMT
Thanx to those who helped in this thread.

I yelled Uncle!
I've used StreamWriter from the System::IO namespace to eliminate the
problems.

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.