Posts filed under 'General MFC'
DateTime and CTime cooperation
Sometimes you might want to pass a current time from managed application to unmanaged and vice versa. The one way to pass time from C# to, lets say, MFC is to calculate total number of seconds from 1.1.70 until current time. Then you will marshal this long value to MFC (probably using COM or network, depends on what you doing) and will create CTime class from it. Here is something you have to consider: DateTime structure by default represents local time, while CTime represents GMT time. Lets say I live in Israel (GMT +2) and my current time is 9:00 AM. Next step I calculating long of total seconds and send it to MFC’s CTime. Now, the CTime thinks it is GMT time. Therefore when I presenting CTIme using ‘Format’ method, I receiving… 11:00 AM. You see, ‘Format’ method counts on fact that CTime is GMT time, and during convertion to string adds GMT delta (in my case + 2 hours). So if you will pass to CTime local time, ‘Format’ method will convert local time to local time again. The point of this story, is you will always have to pass to CTime class GMT time. if not, ‘Format’ method will represent incorrect values (unless you work in +0 time zone). By the way: in case you want to represent original CTime time, instead of ‘Format’ method use ‘FormatGmt’.
1 comment July 3, 2008
Converting CString to integer (VS 2005)
Well, today I got another reason to abandon MFC (this one added to very long list I already have). Consider this very simple task: convertion of CString to integer. Is can something be more basic than this?? Doing this in .NET takes, in worst case, 5 seconds? I took me about a hour to discover how to do that in MFC. In the VS 2003, the following code does works:
CString someText;
int value = atoi(someText);
However, in VS 2005 it doesn’t. atoi function assepts only const char*, and if you casting CString to const char*, you got only first digit of the number. Finally, I found some solution (God bless Internet) that works:
CString someText;
int value = _ttoi(static_cast<LPCTSTR>(someText));
I don’t know, how an average programmer supposed to discover this on his own. From my own experience, I saw string representation in about 10 different forms (in c++, ofc), and this is not trivial at all to convert from one form to other. Pfff…
6 comments January 14, 2008
Nice bug I had with virtual functions in C++
Yesterday I asked to take a look to one bug in our application. Some application feature which was always worked, stopped working. The guy who last touched this part of application, said it is not his fault, and and he didn’t done something that could affect this feature. After 9 hours investigation, I found the problem, and it was so interesting, so I decided to write about it.
Suppose, you have base class ‘BaseClass’, and it defines some virtual method ‘SomeMethod’. All classes derived from BaseClass override this method. For example
class BaseClass
{
public:
virtual void SomeMethod(int arg1, int arg2);
};
class A
{
public:
virtual void SomeMethod(int arg1, int arg2);
};
class B
{
public:
virtual void SomeMethod(int arg1, int arg2);
};
class C
{
public:
virtual void SomeMethod(int arg1, int arg2);
};
… and so on. About 10 classes in different places inside very large and complicate application. In some place in application you call these methods:
for(int i=0; i<10; i++)
{
BaseClass baseClass = (BaseClass ) someClass;
baseClass.SomeMethod(0,0);
}
In for loop above, we using polymorphism to call to right function for each someClass object. So far so good.
Now some guy, decided to add additional parameter to SomeMethod in base class. But he didn’t updated all derived classes, but some of them. The result was as following:
class BaseClass
{
public:
virtual void SomeMethod(int arg1, int arg2, int arg3);
};
class A
{
public:
virtual void SomeMethod(int arg1, int arg2);
};
class B
{
public:
virtual void SomeMethod(int arg1, int arg2, int arg3);
};
class C
{
public:
virtual void SomeMethod(int arg1, int arg2);
};
You see what wrong? Now the method signature in classes A and C differs from one in BaseClass, and therefore polymorphism not working anymore. All they do are declaring virtual functions of their own. So in loop above, when we cast class A to BaseClass, and calling to SomeMethod – actually we calling to method in the base class. This situation however, is not possible in C#: to override virtual functions we use keyword ‘override’, and in case base method signature will change, we will get error during compilation. By the way, even if base method and override method differs only by ‘const’ keyword – this is good enough to kill polymorphism.
Add comment December 28, 2007