Thursday, November 29, 2007

Mixed DLL Loading Problem

When using managed code inside unmanaged dll entry point, it may cause dll loading problem. For more information, follow the link below.

http://msdn2.microsoft.com/en-us/library/aa290048(vs.71).aspx

Monday, November 26, 2007

Be Careful of Naming

Sometimes bad naming may cause compile errors.

I named a managed enum "Event" (__value enum Event) inside a managed class "SopExt" (__gc class SopExt). In this class, I had a private field whose type is the managed enum "Event" and a pair of getter/setter of it. Later, I found that the compiler sometimes had trouble to recognize the expression like this: "sopExt->Event". The compiler sometimes also didn't recognize the type "SopExt::Event".

Obviously, neither expression is wrong. But apperently, the name of the managed enum "Event" is not a good name. Just by changing "Event" to "StreamEvent" (without even changing the name of getter/setter), the compiler error is gone. The reason that caused the compiler error is not clear. It might be that the name "Event" is too general so it confused the compiler? Anyway, good naming is a very important element in programming.

Friday, November 16, 2007

Examine std::vector in VS watch window

vector->_Myfirst[offset] or vector->_Myfirst, count

Thursday, November 15, 2007

Why using managed extension is a pain in the ***?

1. We simply cannot include unmanaged objects in a managed class. We can only include pointers to unmanaged objects.

Tuesday, November 13, 2007

__gc Array Aggregate Initialization

__gc Array Aggregate Initialization doesn't work inside a namespace (except that the method is a member of a gc class). We have to initialize each element one by one.

namespace Sample
{
void ParseString(String* str)
{
...
Char splitter[] = { ',' }; // This will cause link error
// Use the following instead
// Char splitter[] = new Char[1];
// splitter[0] = ',';
...
}
}

Wednesday, October 17, 2007

Switch between Windows debuggers

The key "Debugger" under registry:
\HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\AeDebug
specifies which debugger will be invoked in case of application unhandled exceptions are thrown.

Usually, if Visual Studio is installed, the default debugger will be Visual Studio JIT Debugger("C:\WINDOWS\system32\vsjitdebugger.exe" -p %ld -e %ld); But if we want to use Dr. Watson(drwtsn32 -p %ld -e %ld -g) to debug (creating log and crash dump), we can set the key name of Dr. Watson to "Debugger" and VS JIT Debugger to something else.

Wednesday, September 12, 2007

About Copy Constructor

In the example below, push_back will call the copy constructor of Family implicitly. In this case, it's a deep copy. If we comment out the copy constructor, a default one will gets called, which is a shallow copy.

If we have at least one complex object in a class, we should think about writing our own copy constructor. (choose between deep copy and shallow copy) If there's no complex object in the class, a default copy constructor will do since there's no difference between deep and shallow copy in this case. Remember that if we provide our own copy constructor, we also need to write the destructor so the complex objects can be deallocated.

class Person
{
public:
int age;
Person()
{
age = 0;
}
};

class Family
{
public:
Person* houseHold;
int aptNum;
Family()
{
houseHold = 0;
aptNum = 0;
}
Family(const Family& family)
{
this->houseHold = new Person(*family.houseHold);
this->aptNum = family.aptNum;
}
};

main()
{
vector vecF;
Person* p = new Person();
p->age = 30;
Family* f = new Family();
f->houseHold = p;
f->aptNum = 100;
vecF.push_back(*f);
delete f;
delete p;
cout <<
vecF.at(0).houseHold->age << endl << vecF.at(0).aptNum << endl;
getchar();
}