HnxGC Programing Guide
On This Page
How to upgrade C++ Class to HnxGC ClassHow to upgrade C++ pointer to HnxGC Pointer
How to create HnxGC managed object
The previous article A Closer Look at the HnxGC 'HelloWorld' describes three primary components: Create HnxGC managed object, Upgrade C++ class to HnxGC class, Upgrade C++ pointer to HnxGC pointer. If you do not know what are they, please take a look.
How to upgrade C++ Class to HnxGC Class
Upgrading an C++ class to HnxGC class, you can create an HnxGC managed object that HnxGC will manage its lifetime automatically.
There are two ways to upgrade:Enable Way and Traverse Way.
(1) Enable Way
If the C++ class has not pointer member, use HnxGC macro HNXGC_ENABLE to upgrade.
The following bold text use Enable way to upgrade C++ class to HnxGC class:
class CFoo {
int i;
HNXGC_ENABLE(CFoo)
};
Example:
#include <stdio.h>
#include "hnxGC/hnxGC.h"
using namespace harnix;
class CFoo {
public:
int m_nData;
CFoo() {
m_nData = 100;
}
~CFoo() {
printf("Destructing %p\n", this);
}
HNXGC_ENABLE(CFoo)
};
int main()
{
lp<CFoo> pObj = gcnew CFoo;
printf("[%p].data = %u\n", pObj, pObj->m_nData);
return 0;
}
The printout is: [00382148].data = 100 Destructing 00382148
(2) Traverse Way
If the C++ class has one or more pointer member(s), use HnxGC macro HNXGC_TRAVERSE to upgrade. Note, these pointers should be upgraded to HnxGC pointers first.
To register these pointer members, you can use HnxGC API HNXGC_TRAVERSE_PTR, HNXGC_TRAVERSE_MULTIPLE_BEGIN, HNXGC_TRAVERSE_MULTIPLE_END, HNXGC_TRAVERSE_CHAIN.
The following bold text use Traverse way to upgrade:
class CFoo {
mp<CFoo> m_pNext;
mp<CFoo> m_pPrev;
HNXGC_TRAVERSE(CFoo) {
HNXGC_TRAVERSE_PTR(m_pNext, m_pPrev);
}
};
Example:
#include <stdio.h>
#include "hnxGC/hnxGC.h"
using namespace harnix;
class CFoo {
public:
mp<CFoo> m_pNext, m_pPrev;
int m_nData;
CFoo(int value) {
m_nData = value;
}
~CFoo() {
printf("Destructing %p\n", this);
}
HNXGC_TRAVERSE(CFoo) {
HNXGC_TRAVERSE_PTR(m_pNext, m_pPrev);
}
};
int main()
{
lp<CFoo> pObj = gcnew CFoo(100);
printf("[%p].data = %u\n", pObj, pObj->m_nData);
return 0;
}
The printout is: [00382148].data = 100 Destructing 00382148
How to upgrade C++ pointer to HnxGC Pointer
There are 3 types of HnxGC pointer:
- CLockedPtr (the alternate word is lp)
- CMemberPtr (the alternate word is mp)
- CWeakPtr (the alternate word is wp)
(1) CLockedPtr / lp
A CLockedPtr is a pointer which, reference a HnxGC managed object, The object is 'Locked', that means HnxGC will never collect it unless the pointer is out of scope or re-assigned to others (or NULL).
Typical usages includes:
- Automatic pointer variables within a function;
int main ()
{
lp<CFoo> pObj = gcnew CFoo;
}
Example:
Passing by by reference refers to a method of passing the address of an argument in the calling function to a corresponding parameter in the called function.
Example:
lp<CFoo> g_pObj;
int main ()
{
g_pObj = gcnew CFoo;
}
Assignment between 2 CLockedPtr
By default, HnxGC Assignment use "move" semantic on assignment between two CLockedPtr pointers. The source operand will lose the reference to the object after the assignment operation. If you want to keep the reference, use HnxGC API duplicate instead.
Example:
int main ()
{
lp<CFoo> p1 = gcnew CFoo;
lp<CFoo> p2;
lp<CFoo> p3;
// move the reference from 'p1' to 'p2'
p2 = p1;
// duplicate p2 to p3
p3 = p2.duplicate();
// p1 is cleared, should NOT use it
// p2 and p3 both point to the object
}
(2) CMemberPtr / mp
CMemberPtr is a pointer which, only appear in a C++ class as the type of member variable.
Following bold text define a HnxGC CMemberPtr, compare to the italic text which is the tradional C++ member pointer
class CFoo {
//CFoo * m_pNext;
mp<CFoo> m_pNext;
HNXGC_TRAVERSE(CFoo) {
HNXGC_TRAVERSE_PTR(m_pNext);
}
};
(3) CWeakPtr / wp
A CWeakPtr is a pointer which, doesn't contribute to the liveness of the object it points to.
Example - In the following example, the function parameter is a CWeakPtr. Because conversion among all types of HnxGC pointer is automatic, the input CLockedPtr will be converted to a CWeakPtr. During the period of execution of subroutine, it is up to the caller retain the object alive. subroutine does not need to maintain the object alive, so as to reduce cost.
void func1(wp<CFoo> pObj)
{
...
}
int main ()
{
lp<CFoo> p1 = gcnew CFoo;
func1(p1);
}
How to create HnxGC managed object
Now you know how to upgrade C++ pointer to HnxGC pointer, then can create HnxGC managed objects via HnxGC macro: use HNXGC_NEW (the alternate macro is gcnew) to allocate instance of user defined class from heap; use HNXGC_NEW_NATIVE (the alternate macro is gcnew_native) to allocate a primitive type instance from heap.
Following bold text created diffent HnxGC managed object
lp<CFoo> p = gcnew CFoo;
lp<CFoo> p = gcnew CFoo("pi", 3.1415);
lp<CFoo> p = gcnew CFoo[100];
lp<int> p = gcnew_native(int);
lp<int> p = gcnew_native(int)[100];
Example: Following bold text allocated a buffer from heap via HnxGC. The usage of the buffer is literally the same as traditional C++, however, the buffer will be freed automatically. For comparison, the italic text is the tradional C++ codes.
#include <stdio.h>
#include <string.h>
#include "hnxGC/hnxGC.h"
using namespace harnix;
int main()
{
//char * buf = new char[512];
lp<char> buf = gcnew_native(char) [512];
fgets(buf, 512, stdin);
for (int i = 0; i < strlen(buf); i++) {
fputc(buf[i], stdout);
}
//delete []buf;
return 0;
}