Properties in C++/CLI….The C# look alike !!!

Inherently after writing some code in C#, I wanted everything to be as easy to do like in C#. And could not resist myself writing property like syntax in C++ [ofcourse C++/CLI, threw away the ugly Managed C++ before it was too late for my code to grow into a tree]. Then I learnt that properties are supported in C++.NET too but as always in the ugly way. But in C++/CLI, I was happy enough that the syntax is more elegantly redefined. For instance, there was this boolean member logToStdError in my class, and in my legacy code, the property definition for logToStdError looked like:-

__property bool get_LogToStdError()
{
return logToStdError;
}
__property void set_LogToStdError(bool value)
{
logToStdError = value;
}

Doesn’t that seem like the cat scorching its skin wanting to look like a tiger ? But we need to understand that the Managed C++ is just an extension provided by Microsoft for C++, and is not standard unlike C++/CLI. And then in C++/CLI, the syntax for property was reformed with the property keyword:-

property bool LogToStdError
{
bool get()
{
return logToStdError;
}
void set(bool value)
{
logToStdError = value;
}
}

This makes life bit luxurious, and the compiler takes care of still generating the get_LogToStdError and set_LogToStdError version of the methods. Try defining a method with that name and see what happens.

But the purpose of this entry is not just put another note on C++/CLI Property instead there are 2 cute features that i liked:-

1. If the property that we define is a very simple one, just getting and setting the value of the related member variable, then we can simply declare a statement like this in our class [for the LogToStdError], and the compiler takes care of the under-the-cover activities.

property bool logToStdError;

2. This one I love very much because I wanted this behaviour in a lot of places in my code, and before. It is possible to specify different accessibility levels for the get and the set property accessors. For example,

property bool LogToStdError
{
public:
bool get()
{
return logToStdError;
}
protected internal:
void set(bool value)
{
logToStdError = value;
}
}

The get accessor can be accessed anywhere outside the class in the assembly, but the set accessor can be accessed only inside the current assembly or within the types derived from the type in which LogToStdError is declared. I guess that this facility is not ava
ilable in C#.

Advertisements

Managed Debugging Assistant !!!

The Loader Lock is a synchronization object that hepls to provide mutual exclusion during DLL loading and unloading. It helps to prevent DLLs being re-entered before they are completely initialized [in the DLLMain].

When the some dll load code is executed, the loader lock is set and after the complete intialization it is unset. But there is a possibility of deadlock when threads do not properly synchronize on the loader lock. This mostly happens when threads try to call other other Win32 APIs [LoadLibrary, GetProcAddress, FreeLibrary etc] that also require the loader lock. Often this is evident in the mixed managed/unmanaged code, whereby it is not intentional but the CLR may have to call those APIs like during a call using platform invoke on one of the above listed Win32 API.

For instance, if an unmanaged DLL’s DllMain entry point tries to CoCreate a managed object that has been exposed to COM, then it is an attempt to execute managed code inside the loader lock.

MDA – Managed Debugging Assistant, facility available in .NET 2.0/VS 2005 helps to find out this situation while debugging and pops up a dialog box. Then we can break into the code, have a look at the stack trace and resolve it. The feature can be disabled if not needed.

So what could be the effect of this deadlock ? It saved me whole of time and effort that I would have wasted when such a box poped up in my project, and I do not know if I would have found the reason. If the thread that deadlocks happens to be the GC thread or any thread that loads and unloads my assemblies, I do not have explain further the disasterous effect. And for a programmer like me, new to the .NET environment, who has not yet gotten out of the fascinating external features, will not ponder into the internals.

Do not delete [] a scalar pointer !!!

Recently I got tangled into this problem in my code – Calling a vector dtor for a scalar pointer. We all know that it is perfectly illegal to do that. For example, if we allocate something like this:-

OurClass *p = new OurClass();

and try to delete like this:-
delete []p;

then we are going to end up in trouble. Ofcourse we know that we will end up in trouble. But I have really not given a thought HOW ?

When we allocate an array of items eg. OurClass pa[] = new[5] pa(), the compiler actually allocates the necessary amount of memory, calls the ctors for each allocated class and also prefixes the block of memory of the ‘n’ items allocated with the number of items allocated.

NumItems | OurClassObject1 | OurClassObject2 | …… | OurClassObjectn

But pa always points to the first item in the allocation, thereby the item count prefix remains hidden. When we call delete[] pa, the compiler uses the item count prefix to delete the allocated objects and call the dtors.

Now i think i don’t need explain any further as what happens when i use delete []p, and what junk value will the compiler take from the memory location just before the memory location p believing it to be the item count.

I learnt this interesting information from OldNewThing Blog. Adam Nathan has explained it well with the compiler generated assembly and a bit of excellent code for the dtor.

And what if we do a scalar delete on a vector pointer, there is less harm, you do not unallocate the memory completely, you leave behind remnants of your allocated memory which you cannot reclaim.

Either way, it is better to be disciplined while programming.

Where do you QueryInterface ???

For an ATL class, the QueryInterface is implemented in CComObject. The figure below is the inheritance hierarchy for a class generated by the wizard representing an ATL-COM object.

CComObjectRootBase has an InternalQueryInterface method, which uses the interface map built by the BEGIN_COM_MAP macro to resolve IID -> interface pointer. The BEGIN_COM_MAP macro also defines a method _InternalQueryInterface, which passes the map on to InternalQueryInterface. CComObject implements QueryInterface, and calls _InternalQueryInterface.

NOTE:
CComObjectRootEx: Provides methods to handle object reference count management for both nonaggregated and aggregated objects.

CComObject: Implements IUnknown for a nonaggregated object. It is a template class that takes a class like CSomeClass derived from CComObjectRootEx.

CComObjectNoLock: Implements IUnknown for a nonaggregated object, but does not increment the module lock count in the constructor. ATL uses CComObjectNoLock internally for class factories.

CComCoClass: Defines the object’s default class factory and aggregation model.

Use Of Class Factories !!!

To understand quickly and to explain in the simplest way, Class Factories are the factory classes that create a COM object. A class factory may be responsible for creating one or more COM objects. In the case of COM OutOfProc servers, the server registers the class factories for objects that it can create in a system-global table using CoRegisterClassObject. Whenever a client does CoGetClassObject for a CLSID, the COM run-time can look it up in the system global table, and return the factory instance. The case with InProc servers is also similar but through the DLLGetClassObject.

The point here is that class factories are required [irrespective of how they exist physically in the servers, either as seperate instances or the COM object itself behaving as a factory for the objects of that type], they abstract the creation of the COM object through IClassfactory::CreateInstance.

Unsafe Operations with STL !!!

It is UNSAFE to do any operation on an STL container that will modify its size while holding a reference to one of its exisiting element. What could happen is, when you do an operation, say push_back on a vector, it determines if there is enough space available to add a new element. If there is not sufficient space available, it allocates new space for whole of the data structure and deletes the old buffer. At this point, any reference to one of its elements created prior to push_back would have gotten corrupted.

For example, the following usage of code is dangerous when used within a single scope.

SomeClass &sc = m_Vector.back();
m_Vector.push_back(someotherobject);
.
.
.
sc.SomeMethodCall(); // Code might crash here.

Consoles for Mr.GUI !!!

Learnt something new, a small one but very useful.
Many times I have seen GUI applications accompanied by console windows that show logs or trace information of the application. How do we do that for our application ?

Any GUI application can create its own console window just by calling AllocConsole Win32 API. Actually any process can use that API to allocate a new console. And the application must also learn to be disciplined enough to FreeConsole. Ok, fine. I used that in my small MFC application and was happy to see the console. But I did not see anything displayed on the console. As we know, each process has its own stdin, stdout and stderr. So redirect the console output of your parent application to the console. How do you do that ?

Use the FILE *freopen(const char *path, const char *mode, FILE *stream); API. The freopen function closes the file currently associated with stream and reassigns stream to the file specified by path. By that way, call freopen as follows:-

FILE *fpStdOut = freopen (“CONOUT$”, “w”, stdout);

This means that I want to reassign the standard console output stdout with the console output of the parent application CONONUT$. So any printf calls will print the characters on the console. Cool !!!