Home > Support > HelloWorld

Hello World - Begin the first HnxGC application

After installation of HnxGC, you can begin your first HnxGC application right now.

To use HnxGC automatic memory management in your C++ application, you must include HnxGC header files in your C++ source code. For example, You can insert the following C++ statement

#include "hnxGC.h"

between native header files and your HnxGC managed codes. You can also define some preprocessing macros to control the default behavior of HnxGC. click here to see more ...

Once you have include the HnxGC header files, you are free to use all HnxGC features in the code that follows the HnxGC header files. The system will automatically take care of the loading and initializing the HnxGC.dll and related modules. You can use HnxGC after or before the control passed to main() function, such as using HnxGC in the C++ global initialization stage. There is no need to call explicitly any HnxGC initialization routine before using it.

Here is a very simple example of HnxGC application. You can copy & paste these codes to a C++ file and build the first HnxGC application.

#include "hnxGC.h"

int main()
{
    gcptr<char> p;              // replace C/C++: char * p;

    p = gcnew char [100];       // replace C/C++: p = new char [100];

    //  garbage collect, no need C/C++: delete [] p;

    return 0;
}

If you have properly set up the searching path for include files and library files in your C++ development environment, it should be no problem in building this application and get it run successfully with the HnxGC.dll in the same directory or in one of the listed path of `PATH' environment variable.

By default, HnxGC will automatically use #pragma comment (lib, ...) to place a library-search record in object file to instruct linker to search for "HnxGC.lib". If you don't want this behavior, you can define the macro HNXGC_CONFIG_NO_DEFAULT_LIB before the "hnxGC.h" header file, and explicitly link with a proper HnxGC library.

More Examples

(1) Create managed object / array from native type.

You can use 'gcnew' macro to create an object or array of native type in the managed heap.

The 'gcnew' macro is defined as synonym macro HNXGC_NEW. If you want to temporarily use Microsoft .NET CLR's `gcnew' to create a CLR managed object, you can #undef the 'gcnew' macro prior to the code and #define gcnew HNXGC_NEW to re-enable using HnxGC's gcnew.

#include "hnxGC.h"

class CBar {
public:
    int         i;
    double      d;
};

gcptr<CBar> p = gcnew CBar;               // create a single object

int main()
{
    p->i = 100; p->d = 3.1415;            // member variable access

    gcptr<CBar> p2 = gcnew CBar[100];     // create an array of 100 objects

    gcptr<int> p3 = gcnew int;            // create an integer object

    gcptr<double> p4 = gcnew double[10];  // create an array of 10 double values

    return 0;
}

(2) Define a managed class / type.

To define a managed class that supports more features, you can include a line - HNXGC_ENABLE(<class name>) in the declaration of the class.

#include "hnxGC.h"

class CFoo {
public:
    HNXGC_ENABLE(CFoo)                    // declare a HnxGC managed class
    gcptr<CFoo>     m_pNext;
    gcptr<CFoo>     m_pPrev;
    double          m_vData;
};

int main()
{
    gcptr<CFoo> p = gcnew CFoo;           // create a single object
    p->m_pPrev = p;                       // circular reference itself
    p->m_pNext = gcnew CFoo;              // reference and hold another object

    return 0;
}

(3) Interior Pointer - point to the interior of an object

The interior pointer mechanism allows you to reference an address at the interior of an object and meanwhile hold the object alive by a single ordinary pointer. In the following example, the 'pDouble' smart pointer can point to the interior address of various type of objects. There is no difference from the point of view of users of the `pDouble', it can be assigned to any place that need a pointer of `double' type.

#include "hnxGC.h"

class CFoo {
public:
    HNXGC_ENABLE(CFoo)
    gcptr<CFoo>     m_pNext;
    gcptr<CFoo>     m_pPrev;
    double          m_vData;
    gcptr<double>   m_pData;
};

class CBar {
public:
    int         i;
    double      d;
};

int main()
{
    gcptr<double> pDouble;

    pDouble = gcnew double;                             // ref & hold a double

    gcptr<CFoo> pCFoo = gcnew CFoo;
    pDouble = interior_cast(pCFoo, &pCFoo->m_vData);    // ref `m_vData' & hold 'pCFoo'
    pCFoo->m_pData = pDouble;                           // ref `m_vData' & hold itself circularly
    pCFoo = nullptr;

    gcptr<CBar> pCBar = gcnew CBar;
    pDouble = interior_cast(pCBar, &pCBar->d);          // ref `d' & hold 'pCBar'
    pCFoo = nullptr;

    gcptr<double> pArray = gcnew double[100];
    pDouble = interior_cast(pArray, pArray + 10);       // ref an element & hold the whole array
    pArray = nullptr;

    return 0;
}

(4) Dynamic Associated Destructor

You can dynamically associate a destructor to an existing object. For example, you can associate a closing action to an existing FILE handle, so that when there is no reference to the FILE handle, the associated action will be invoked to close the file.

A function HnxGC::AutoCloseFile() is provided to wraps such behavior for your convenience. People can directly access the FILE structure as "gcptr<FILE>"

#include <stdio.h>

#include "hnxGC.h"

int main ()
{
    gcptr<FILE> fp = HnxGC::AutoCloseFile(fopen("myfile.txt", "w"));
    if (fp) {
        fputs("Hello\n", fp);
    }
    // the file is automatically closed when `fp' is out of scope.
    return 0;
}

See Also:
Programming Guide
Home | Download | Terms of Use | Privacy Statement | Contact Us
Copyright@ 2008 hnxgc.harnixworld.com, All rights reserved.