load help;

@[name]
daovm.interface
@[name]

@[title]
Programming with The C Interfaces
@[title]


################################################################################
################################################################################
#### Embedding Dao Virtual Machine
################################################################################
################################################################################
@[name]
daovm.interface.embedding
@[name]

@[title]
Embedding Dao VM
@[title]

@[text]

@[section]
A Simple Example
@[section]

@[subsection]
Initializing Dao Runtime
@[subsection]

Before doing anything with Dao as a library, one must call
@[green]DaoInit()@[green] to initialize it first:

@[code(cxx)]
// Initialize Dao:
DaoVmSpace *vmspace = DaoInit( NULL );
@[code(cxx)]
This function will return a @[green]DaoVmSpace@[green] object,
which can be used to load Dao scripts or modules.
It can optionally take a @[cyan]char*@[cyan] parameter,
which is assumed to be the path and name of the application,
and is used to add additional searching paths.

@[comment]
Before you start to use the @[green]DaoVmSpace@[green] object
to run Dao scripts or load Dao modules, you may set some options
in the object, e.g:
@[code(cxx)]
DaoVmSpace_SetOptions( vmspace, DAO_EXEC_DEBUG );
@[code(cxx)]
@[comment]

@[subsection]
Load A Script File
@[subsection]

Once you have a @[green]DaoVmSpace@[green] object, you can start
to run Dao scripts or load Dao modules using this object.
If you have a main script file and all you need to do is to run the file,
you can simply call:

@[code(cxx)]
// Load "myscript.dao":
DaoVmSpace_Load( vmspace, "myscript.dao" );
@[code(cxx)]

@[subsection]
Finalize Dao Runtime
@[subsection]

After you are done with Dao, you may call the following function
to make sure, Dao is properly finalized (waiting for unjoined threads
to finish and the garbage collector to finish, and deallocating
some internal data structures etc.).
@[code(cxx)]
// Finalize (or Quit) Dao:
DaoQuit();
@[code(cxx)]

@[subsection]
Putting These Codes Together
@[subsection]

Putting these codes together, embedding Dao can be as simple as,
@[code(cxx)]
// Initialize Dao:
DaoVmSpace *vmspace = DaoInit( NULL );
// Load "myscript.dao":
DaoVmSpace_Load( vmspace, "myscript.dao" );
// Finalize (or Quit) Dao:
DaoQuit();
@[code(cxx)]


@[section]
A Slightly More Advanced Example
@[section]

In Dao, each single script file is represented by one namespace object.
And each namespace object has access to the public global constants and 
variables defined in the files that this file has loaded.
To do anything interesting, one must obtain the namespace object
for the file of interest.


@[subsection]
Obtaining The Namespace Object
@[subsection]

Following the above example, if you want to call a function defined
in "myscript.dao" (or in the files it has loaded), you can simple
store the returned namespace object in a variable,
@[code(cxx)]
// Load "myscript.dao" and obtain the namespace object:
DaoNamespace *nspace = DaoVmSpace_Load( vmspace, "myscript.dao" );
@[code(cxx)]


@[subsection]
Obtaining The Function Object
@[subsection]

To find the function you want to call,
@[code(cxx)]
// Find an object named "myfunction":
DaoValue *value = DaoNamespace_FindData( nspace, "myfunction" );
// Try to cast it to a function object:
DaoRoutine *myfunc = DaoValue_CastRoutine( value );
@[code(cxx)]
If "myfunction" is indeed a function, @[cyan]myfunc@[cyan] will not be NULL.


@[subsection]
Obtaining A Process Object
@[subsection]

Now to call the function, you will need another type of object:
@[green]DaoProcess@[green], which represents a virtual machine process
and is responsible for executing scripts.
You can directly call @[green]DaoProcess_New()@[green] to create a new
process object, but normally the better to get a process object is to
acquire it from a @[green]DaoVmSpace@[green] object:
@[code(cxx)]
// Acquire a process object:
DaoProcess *proc = DaoVmSpace_AcquireProcess( vmspace );
@[code(cxx)]

@[subsection]
Prepare Parameter Values
@[subsection]

Now suppose the function "myfunction" needs to take an integer as its first
parameter and a string as the second. To call it, we will need to prepare
parameters that can be passed to this function.
The simplest way to do this is to use the data "factory" methods that
are associated with the process type @[green]DaoProcess@[green].
Such methods are normally begin with @[green]DaoProcess_New@[green].
For example, to prepare an integer value and a string value, one can do,

@[code(cxx)]
// Prepare an integer and a string:
DaoInteger *ivalue = DaoProcess_NewInteger( proc, 123 );
DaoString  *svalue = DaoProcess_NewMBString( proc, "abc", -1 );
@[code(cxx)]
The third parameter of @[green]DaoProcess_NewMBString()@[green]
is the number of bytes in the C string, and a negative value can be
used to indicate the C string is NULL terminated.


To use these two new values in the parameter list to call "myfunction",
you can do,
@[code(cxx)]
DaoValue *params[2];
params[0] = (DaoValue*) ivalue;
params[1] = (DaoValue*) svalue;
@[code(cxx)]
Or you can simply do,

@[code(cxx)]
// Get the last two values:
DaoValue **params = DaoProcess_GetLastValues( proc, 2 );
@[code(cxx)]
which will return last created two values in an array.


@[subsection]
Call The Function
@[subsection]

Now we are ready to call the function we obtained before with
the prepared values,
@[code(cxx)]
// Call the function:
DaoProcess_Call( proc, myfunc, NULL, params, 2 );
@[code(cxx)]
For class methods, a class instance object can be passed to this function
as the third parameter, or it can be passed as the first value of 
@[cyan]params@[cyan].
Please note that, this function can handle overloaded functions automatically!
So you do not need to do anything for that.
This function will return zero on success, or other values with errors.


@[subsection]
Retrieve The Returned Value
@[subsection]

If the function returns a value, you can obtain it by,
@[code(cxx)]
// Obtain the returned value:
DaoValue *retvalue = DaoProcess_GetReturned( proc );
@[code(cxx)]
If the returned value is supposed to be of certain type,
you can cast it to that type by using one of the 
@[green]DaoValue_CastXXX()@[green] functions,
or directly convert it to a proper C type by using one of the
@[green]DaoValue_TryGetXXX()@[green] functions.
For example, if "myfunction" returns an integer,
you can get it by,
@[code(cxx)]
// Get the integer return value
daoint retint = DaoValue_TryGetInteger( retvalue );
@[code(cxx)]

@[subsection]
Release The Process Object
@[subsection]

After you have done with the process object, you can release it
back the @[green]DaoVmSpace@[green] object,
@[code(cxx)]
// Release the process:
DaoVmSpace_ReleaseProcess( vmspace, proc );
@[code(cxx)]
But if you want to use a process object frequently,
you may simply retain it until you no longer need it.
Then you may also need to the follow function to release the cached values
@[code(cxx)]
// Pop the cached values:
DaoProcess_PopValues( proc, 2 );
@[code(cxx)]


@[subsection]
Putting These Codes Together
@[subsection]

@[code(cxx)]
// Load "myscript.dao" and obtain the namespace object:
DaoNamespace *nspace = DaoVmSpace_Load( vmspace, "myscript.dao" );
// Find an object named "myfunction":
DaoValue *value = DaoNamespace_FindData( nspace, "myfunction" );
// Try to cast it to a function object:
DaoRoutine *myfunc = DaoValue_CastRoutine( value );

// Acquire a process object:
DaoProcess *proc = DaoVmSpace_AcquireProcess( vmspace );

// Prepare an integer and a string:
DaoInteger *ivalue = DaoProcess_NewInteger( proc, 123 );
DaoString  *svalue = DaoProcess_NewMBString( proc, "abc", -1 );
// Get the last two values:
DaoValue **params = DaoProcess_GetLastValues( proc, 2 );

// Call the function:
DaoProcess_Call( proc, myfunc, NULL, params, 2 );

// Obtain the returned value:
DaoValue *retvalue = DaoProcess_GetReturned( proc );
// Get the integer return value
daoint retint = DaoValue_TryGetInteger( retvalue );

// Release the process:
DaoVmSpace_ReleaseProcess( vmspace, proc );
@[code(cxx)]

@[text]


################################################################################
################################################################################
#### Extending Dao Virtual Machine
################################################################################
################################################################################
@[name]
daovm.interface.extending
@[name]

@[title]
Extending Dao VM
@[title]

@[text]

In the help entry @[node]daovm.interface.embedding@[node], it has been 
demonstrated that embedding Dao is extremely simple.
Here we will demonstrate that extending Dao is also extremely simple.
Since Dao supports explicit type specification in function parameter lists,
you will not need to write a lot of boilerplate codes to check and 
convert function parameters from Dao data types to C/C++ data types.
This means writing wrapping functions (Dao-callable C functions) 
is significantly simpler than writing wrapping functions
for other languages such as Python or even Lua.


@[section]
The First Simple Extending Module
@[section]

All Dao-callable C functions must have prototype similar to the following
example,
@[code(cxx)]
void MyCFunction( DaoProcess *proc, DaoValue *param[], int nparam )
{
	printf( "Hello Dao!\n" );
}
@[code(cxx)]

Each Dao extending module must provide an entry function,
@[code(cxx)]
// Entry function for each C/C++ module:
int DaoOnLoad( DaoVmSpace *vmspace, DaoNamespace *ns );
@[code(cxx)]
This function will be called automatically to allow the module
to register its functions and types etc.
The first parameter is the @[green]DaoVmSpace@[green] instance
which is responsible for loading and managing the module.
And the second parameter is the namespace object that will
represent this module, so all the functions and types etc.
should be registered to this namespace.


This function can also be named as @[cyan]DaoXXX_OnLoad@[cyan],
where @[cyan]XXX@[cyan] is the module name that will appear
in a load statement such as @[code(cxx)]load XXX@[code(cxx)]
or @[code(cxx)]load path.XXX@[code(cxx)].


To register functions to a namespace, one can use one of the
following interface functions of @[green]DaoNamespace@[green],
@[code(cxx)]
// Function to register a single function:
DaoRoutine* DaoNamespace_WrapFunction( DaoNamespace *self,
                                       DaoCFunction fp, 
                                       const char *proto );

// Function to register multiple functions:
int DaoNamespace_WrapFunctions( DaoNamespace *self, DaoFuncItem *items );
@[code(cxx)]
We will come to the second function later.
For the first function, the first parameter is the namespace to which
the function is registering to; the second is the function pointer to
the function that needs to be registered (@[cyan]MyCFunction@[cyan] in this case);
and the last parameter is the Dao function prototype for the registered function.


So you can register the above function @[cyan]MyCFunction@[cyan] as the following,
@[code(cxx)]
// Register function:
DaoNamespace_WrapFunction( nspace, MyCFunction, "HelloDao()" );
@[code(cxx)]
So that this function can be called in Dao by name @[cyan]HelloDao@[cyan]
without any parameter.


To sum it up, the simplest Dao extending module could be the following,
@[code(cxx)]
#include "dao.h"
#include "stdio.h"
static void MyCFunction( DaoProcess *proc, DaoValue *param[], int nparam )
{
	printf( "Hello Dao!\n" );
}
int DaoOnLoad( DaoVmSpace *vmspace, DaoNamespace *nspace )
{
	DaoNamespace_WrapFunction( nspace, MyCFunction, "HelloDao()" );
	return 0;
}
@[code(cxx)]
To compile it, you will need to add the Dao header file path to your compiling
option. And you will also need to add the following preprocessor definitions:
@[list]
-- On Win32: @[green]WIN32@[green];
-- On Unix: @[green]UNIX@[green];
-- On Mac OSX: @[green]MAC_OSX@[green];
@[list]
For linking, on Windows you will need to link the module against the Dao library.
But on the other platforms, you can simply use the following flags,
@[list]
-- On Unix: @[green]-rdynamic@[green];
-- On Mac OSX: @[green]-undefined dynamic_lookup@[green];
@[list]


@[section]
The Second Simple Extending Module
@[section]

Now we will demonstrate how to create a function that can accept
parameters and return a value.
Suppose we want to create C function with the following Dao function prototype,
@[code]
# Dao function prototype
MyTest( id :int, name :string, extra = 0 ) => float
@[code]
So this function will take an integer parameter, a string parameter and 
an extra integer parameter with default value. This prototype also indicates
that it will return a float.


In the C function, it is very easy to convert Dao data type to C data type,
and to return C data type to Dao,
@[code(cxx)]
void MyTestInC( DaoProcess *proc, DaoValue *param[], int nparam )
{
	daoint id = DaoValue_TryGetInteger( param[0] );
	char *name = DaoValue_TryGetMBString( param[1] );
	daoint extra = DaoValue_TryGetInteger( param[2] );
	printf( "MyTest: %i %s %i\n", id, name, extra );
	DaoProcess_PutFloat( proc, 0.5*(id + extra) );
}
@[code(cxx)]
As you can see, there are no boilerplate codes to check the number of parameters
or the type of parameters.
When the execution reaches the function body of @[cyan]MyTestInC()@[cyan],
it is guaranteed that all the parameter values are available with correct types.


Actually the @[cyan]DaoValue_TryGetXXX()@[cyan] methods did check the value type,
but in this case, they will always succeed. So if you include the header file
@[green]daoValue.h@[green] in your source file, you can simple write the 
function as the following to completely (and safely) remove the type checking,
@[code(cxx)]
void MyTestInC( DaoProcess *proc, DaoValue *param[], int nparam )
{
	daoint id = param[0]->xInteger.value;
	char *name = DString_GetMBS( param[1]->xString.data );
	daoint extra = param[2]->xInteger.value;
	printf( "MyTest: %i %s %i\n", id, name, extra );
	DaoProcess_PutFloat( proc, 0.5*(id + extra) );
}
@[code(cxx)]
But the downside of this is that you need to be familiar with the internal Dao
data structures.


These @[cyan]DaoValue_TryGetXXX()@[cyan] functions will convert the Dao values
to the requested C values.
And @[cyan]DaoProcess_PutFloat()@[cyan] will put a float value at proper location
as the returned value of the C function.
Please see the following section(s) for more details.


Now this function can be registered as:
@[code(cxx)]
// Register a function with parameters and returned value:
DaoNamespace_WrapFunction( nspace, MyTestInC, "MyTest(id:int,name:string,extra=0)=>float" );
@[code(cxx)]





@[section]
Basic wrapping C/C++ type
@[section]

There are two ways to extend Dao with user defined C/C++ types.
One is to wrap it around by a @[green]DaoCdata@[green] object,
and access it as an opaque pointer.
This is the standard way to wrap existing C/C++ types.
The other is to define a customized C type, and use it in the same way as the first.
A customized C type is a C structure sharing the same header fields as
@[green]DaoCdata@[green], which can make sharing types between Dao and C simpler
(especially for garbage collection).
Wrapped C/C++ types and customized C types can be added to Dao in almost the identical way,
so I will introduce the wrapped types first, and then the customized types should be very
easy to understand.


@[subsection]
Type information structure
@[subsection]

A C/C++ type can be used in Dao if only if it is registered in a Dao namespace
with a type information structure through,
@[code(cxx)]
DaoType* DaoNamespace_WrapType( DaoNamespace *self, DaoTypeBase *typer, int opaque );
int DaoNamespace_WrapTypes( DaoNamespace *self, DaoTypeBase *typer[] );
@[code(cxx)]
The @[cyan]opaque@[cyan] parameter must be set to 1 for wrapped types,
and 0 for customized types.


@[subsubsection]Structure definition@[subsubsection]

Here @[green]DaoTypeBase@[green] is defined as the following,
@[code(cxx)]
/* Type information structure for creating Dao types for C/C++ types: */
struct DaoTypeBase
{
	const char    *name;      /* type name; */
	DaoTypeCore   *core;      /* data used internally; */
	DaoNumItem    *numItems;  /* constant number list: should end with a null item; */
	DaoFuncItem   *funcItems; /* method list: should end with a null item; */

	/* typers for super types, to create c type hierarchy: */
	DaoTypeBase   *supers[ DAO_MAX_CDATA_SUPER ];

	/* function(s) to cast a C/C++ type to and from one of its parent type: */
	FuncPtrCast    casts[ DAO_MAX_CDATA_SUPER ];

	/* function to free data: */
	void  (*Delete)( void *self );

	/* Get garbage collectable fields (Dao data types with refCount by the type): */
	void  (*GetGCFields)( void *self, DArray *values, DArray *arrays, DArray *maps, int remove );
};
@[code(cxx)]
This structure defines the set of type information needed to create a corresponding Dao type.
Obviously each type needs a name, which can be set in the first field of this structure.
The second field is reserved for internal use for storing wrapped member constants and methods.


@[subsubsection]Member constant numbers and methods@[subsubsection]

The third field @[green]numItems@[green] can be used to specify a list of member constant numbers,
which are defined in an array of the following structure:
@[code(cxx)]
struct DaoNumItem
{
	const char *name;   /* contant name; */
	int         type;   /* number type; */
	double      value;  /* number value; */
};
@[code(cxx)]
The number type should be one of @[green]DAO_INTEGER@[green], @[green]DAO_FLOAT@[green]
and @[green]DAO_DOUBLE@[green]. The array should be terminated with a item with null name:
@[code(cxx)]
static DaoNumItem myTypeNumbers[] =
{
	{ "MODE_ONE", DAO_INTEGER, MODE_ONE },
	{ "MODE_TWO", DAO_INTEGER, MODE_TWO },
	{ NULL, 0, 0 }
};
@[code(cxx)]
If the type has no member constant numbers, it can be simply set to NULL.


The fourth field @[green]funcItems@[green] can be used to specify a list of member methods,
which are defined in an array of the following structure:
@[code(cxx)]
struct DaoFuncItem
{
	DaoCFunction  fpter;  /* C function pointer; */
	const char   *proto;  /* function prototype: name( parlist ) => return_type */
};
@[code(cxx)]
where the two fields @[cyan]fpter@[cyan] and @[cyan]proto@[cyan]
should be the same as they would in the parameter list of:
@[code(cxx)]
DaoRoutine* DaoNamespace_WrapFunction( DaoNamespace *self,
                                       DaoCFunction fp, 
                                       const char *proto );
@[code(cxx)]


@[subsubsection]Base types and casting functions@[subsubsection]

The fifth field @[green]supers@[green] can be use to expose the inheritance structure
of C/C++ types to Dao. To do this, one just need to set the @[green]supers@[green]
array to the type information structures of the parent types, and terminate the array
with a NULL pointer.


If the wrapped type is a C++ class with virtual method(s) or
virtual base(s), Dao will need to know how to cast this type to and from its parent
type properly. This can be done by specifying a list of cast functions in the sixth
field @[green]casts@[green] of the type structure.


If the C++ class has virtual method(s) but no virtual base(s), the cast function should
be provided in the following form,
@[code(cxx)]
void* cast_Sub_Base( void *data, int down_casting )
{
	if( down_casting ) return static_cast<Sub*>( (Base*)data );
	return dynamic_cast<Base*>( (Sub*)data );
}
@[code(cxx)]
And if the C++ class has virtual base(s), the cast function should be like,
@[code(cxx)]
void* cast_Sub_Base( void *data, int down_casting )
{
	if( down_casting ) return dynamic_cast<Sub*>( (Base*)data );
	return dynamic_cast<Base*>( (Sub*)data );
}
@[code(cxx)]


@[subsubsection]Deallocation and GC handling@[subsubsection]

If the C/C++ type should not be deallocated by the standard C function
@[green]free()@[green], a customized deallocation function must be specified for the
type structure. For wrapped C/C++ types, the @[cyan]self@[cyan] parameter passed
to the deallocation function will be the opaque C/C++ pointer,
and for customized C types, it will be the whole objects that have the same header fields
as @[green]DaoCdata@[green].


The last field @[green]GetGCFields@[green] can be normally set to NULL.
But if the C/C++ type may retain reference(s) to Dao data structures that
can form potentially cyclic referencing relationships, this field must be set
to a proper function.
The main purpose of this function is to expose the references retained by the C/C++
type to Dao garbage collector.
In this function, the pointers of Dao data that are directly referenced by the C/C++ type
should be pushed to the @[cyan]values@[cyan] parameters; and for Dao data that are
referenced through @[green]DArray@[green] structures, these @[green]DArray@[green] structures
should be pushed into the @[cyan]arrays@[cyan]; and for those that are referenced
through @[green]DMap@[green] structures, these @[green]DMap@[green] structures
should be pushed into the @[cyan]maps@[cyan].


This function is called with a zero @[cyan]remove@[cyan] parameter automatically by 
the garbage collector (GC) when an object of the C/C++ type needs to be scanned to determine 
if it is no longer reachable from the program.
It is also called before the object is deallocated by the GC,
this time the @[cyan]remove@[cyan] parameter is set to one,
and in this case, the @[green]GetGCFields@[green] must break the references that
are pushed into the @[cyan]values@[cyan], @[cyan]arrays@[cyan] and @[cyan]maps@[cyan] arrays.
This is necessary, because some of the objects referenced by the C/C++ object
can be deallocated by the GC, breaking references to them will avoid posible double deletion.


@[subsection]A simple example@[subsection]

Given the following C++ class,
@[code(cxx)]
class ClassOne
{
	public:
	int  value;

	enum{ CLASSONE_AA, CLASSONE_BB };

	ClassOne( int v );

	int Method( const char *s );
};
@[code(cxx)]
It can be wrapped in the following way,
@[code(cxx)]
// Declare the wrapper functions first:
static void dao_ClassOne_ClassOne( DaoProcess *proc, DaoValue *p[], int n );
static void dao_ClassOne_Method( DaoProcess *proc, DaoValue *p[], int n );
// List of constant member numbers for the enums:
static DaoNumItem ClassOneNumbers[] =
{
	{ "CLASSONE_AA", DAO_INTEGER, CLASSONE_AA },
	{ "CLASSONE_BB", DAO_INTEGER, CLASSONE_BB },
	{ NULL, 0, 0 }
};
// List of member constructors or methods of ClassOne:
static DaoFuncItem ClassOneMethods[] =
{
	// Methods with the same name as the type name are constructors:
	{ dao_ClassOne_ClassOne,  "ClassOne( v :int )" },
	{ dao_ClassOne_Method,    "Method( self :ClassOne, s :string ) => int" },
	{ NULL, NULL }
};
static void ClassOne_Delete( void *self )
{
	delete (ClassOne*) self;
}
// The type information structure for ClassOne:
static DaoTypeBase ClassOne_Typer = 
{
	"ClassOne", NULL, ClassOneNumbers, ClassOneMethods,
	{NULL}, {NULL}, ClassOne_Delete, NULL
};
// The Dao type structure for ClassOne:
DaoType *dao_type_ClassOne = NULL;

static void dao_ClassOne_ClassOne( DaoProcess *proc, DaoValue *p[], int n )
{
	// Get the integer parameter;
	daoint v = DaoValue_TryGetInteger( p[0] );
	// Create a ClassOne instance:
	ClassOne *self = new ClassOne( v );
	// Wrap the instance with Dao type structure:
	DaoProcess_PutCdata( proc, self, dao_type_ClassOne );
}
static void dao_ClassOne_Method( DaoProcess *proc, DaoValue *p[], int n )
{
	// Get the ClassOne instance:
	ClassOne *self = (ClassOne*) DaoValue_TryCastCdata( p[0], dao_type_ClassOne );
	// Get the string parameter:
	char *s = DaoValue_TryGetMBString( p[1] );
	int res = self->Method( s );
	// Return the integer result:
	DaoProcess_PutInteger( proc, res );
}
int DaoOnLoad( DaoVmSpace *vmSpace, DaoNamespace *nspace )
{
	// Wrap ClassOne as an opaque C/C++ type:
	dao_type_ClassOne = DaoNamespace_WrapType( nspace, & ClassOne_Typer, 1 );
	return 0;
}
@[code(cxx)]


Since the @[cyan]value@[cyan] member of ClassOne is a public member,
it is reasonable to add a getter and a setter method to wrapped ClassOne type.
To add a getter, one only needs to register a method with name @[green].field@[green]
and no extra parameter.
And for a setter, the method name must be @[green].field=@[green],
and it must also accept a parameter with type the same as the value 
that can be assigned.
For example, for the @[cyan]value@[cyan] member,
one can added the following to the @[cyan]ClassOneMethods@[cyan] list,
@[code(cxx)]
// the getter and setter:
	{ dao_ClassOne_GETF_value,  ".value( self :ClassOne ) => int" },
	{ dao_ClassOne_SETF_value,  ".value=( self :ClassOne, value :int )" },
@[code(cxx)]
Here the name @[cyan]dao_ClassOne_GETF_value@[cyan] 
and @[cyan]dao_ClassOne_GETF_value@[cyan] are completely arbitrary.
They can be implemented in the following way,
@[code(cxx)]
static void dao_ClassOne_GETF_value( DaoProcess *proc, DaoValue *p[], int n )
{
	ClassOne *self = (ClassOne*) DaoValue_TryCastCdata( p[0], dao_type_ClassOne );
	DaoProcess_PutInteger( proc, self->value );
}
static void dao_ClassOne_SETF_value( DaoProcess *proc, DaoValue *p[], int n )
{
	ClassOne *self = (ClassOne*) DaoValue_TryCastCdata( p[0], dao_type_ClassOne );
	self->value = DaoValue_TryGetInteger( p[1] );
}
@[code(cxx)]


@[subsection]An advanced example@[subsection]

Now given the following class that is derived from @[cyan]ClassTwo@[cyan],
@[code(cxx)]
class ClassTwo : public ClassOne
{
	public:
	virtual void VirtualMethod( int i, float f );
};
@[code(cxx)]
Because this class has a virtual method, if we want Dao classes can be
derived from @[cyan]ClassTwo@[cyan] and reimplement its virtual functions,
the wrapping will be a bit more sophisticated.
First, we will need to define a "proxy" class that is derived from
@[cyan]ClassTwo@[cyan] and reimplements its virtual function 
such that this reimplemented function can check for
a Dao reimplementation of the function and invoke it if it exists.
When an instance of @[cyan]ClassTwo@[cyan] needs to be created,
an instance of this proxy class will be created and returned
instead of the original @[cyan]ClassTwo@[cyan].


Here is an example of such proxy class,
@[code(cxx)]
class Dao_ClassTwo : public ClassTwo
{
	public:

	DaoCdata *dao_cdata;

	Dao_ClassTwo();
	~Dao_ClassTwo();

	int VirtualMethod( int i, float f );
};
@[code(cxx)]
This proxy class will need to maintain a reference to the wrapper object,
so an extra field @[cyan]dao_cdata@[cyan] is declared in the class.
This wrapper object can be pre-allocated in the constructor of @[cyan]Dao_ClassTwo@[cyan],
@[code(cxx)]
Dao_ClassTwo::Dao_ClassTwo()
{
	dao_cdata = DaoCdata_New( dao_type_ClassTwo, this );
	DaoGC_IncRC( (DaoValue*)dao_cdata );
}
@[code(cxx)]
Here the @[cyan]dao_type_ClassTwo@[cyan] is the Dao type object for @[cyan]ClassTwo@[cyan],
and can be obtained in the same way as @[cyan]dao_type_ClassOne@[cyan].
Now that @[cyan]Dao_ClassTwo@[cyan] has a reference to a @[green]DaoCdata@[green]
object, the @[green]GetGCFields@[green] field of the type information structure
for @[cyan]ClassTwo@[cyan] should be set to a proper function, which will be provided later.
The destructor should also be handled this reference properly by,
@[code(cxx)]
Dao_ClassTwo::~Dao_ClassTwo()
{
	if( dao_cdata ){ // Could have been set to NULL by the GC:
		// Set the opaque pointer of dao_cdata to NULL, so that the deallocator
		// of DaoCdata will not attempt to call the deallocator of the opaque pointer:
		DaoCdata_SetData( dao_cdata, NULL );
		DaoGC_DecRC( (DaoValue*) dao_cdata );
	}
}
@[code(cxx)]


Then the @[cyan]VirtualMethod()@[cyan] could be implemented in the following way,
@[code(cxx)]
int Dao_ClassTwo::VirtualMethod( int i, float f )
{
	DaoVmSpace *vmspace = DaoVmSpace_MainVmSpace();
	DaoProcess *proc = NULL;

	// Try to get the instance of a derived Dao class:
	DaoObject *object = DaoCdata_GetObject( dao_cdata );
	if( object == NULL ) goto CallDefault;

	// Try to get a method named "VirtualMethod":
	DaoRoutine *method = DaoObject_GetMethod( object, "VirtualMethod" );
	if( method == NULL ) goto CallDefault;

	// Check if the method is a C/C++ wrapper function:
	if( DaoRoutine_IsWrapper( method ) ) goto CallDefault;

	// Acquire a process object to execute the re-implemented virtual function:
	proc = DaoVmSpace_AcquireProcess( vmspace );
	
	// Prepare function call parameters:
	DaoProcess_NewInteger( proc, i );
	DaoProcess_NewFloat( proc, f );
	DaoValue **params = DaoProcess_GetLastValues( proc, 2 );

	// Resolve possible overloading using the parameters:
	// This can be merged with DaoProcess_Call(), if the error code returned
	// by DaoProcess_Call() is checked an properly handled.
	method = DaoRoutine_Resolve( method, object, params, 2 );
	if( method == NULL ) goto CallDefault;

	// Run the re-implemented function:
	if( DaoProcess_Call( proc, method, object, params, 2 ) ) goto ErrorCall;

	// Check the returned value:
	DaoValue *res = DaoProcess_GetReturned( proc );
	if( DaoValue_CastInteger( res ) ) goto ErrorCall;

	int ires = DaoValue_TryGetInteger( res );

	// Release the process object:
	DaoProcess_Release( vmspace, proc );

	return ires;

CallDefault:
	if( proc ) DaoProcess_Release( vmspace, proc );
	return ClassTwo::VirtualMethod( i, f );
ErrorCall:
	DaoProcess_Release( vmspace, proc );
	// Do something;
	return 0;
}
@[code(cxx)]


Now we will define a function that can be set to the @[cyan]GetGCFields@[cyan]
field of the type information structure of @[cyan]ClassTwo@[cyan].
@[code(cxx)]
static void Dao_ClassTwo_GetGCFields( void *self0,
		DArray *values, DArray *arrays, DArray *maps, int remove )
{
	Dao_ClassTwo *self = (Dao_ClassTwo*) self0;
	if( self->dao_cdata == NULL ) return;
	DArray_Append( values, self->dao_cdata );
	if( remove ){
		// If this object cannot be deallocated because some other C/C++ objects
		// are using it, here is the right place to set the wrapped pointer (namely
		// this object) of dao_cdata to NULL, so that no deallocation will be
		// invoked for this object.
		//
		// For example, in some GUI library, if a widget has a parent, the parent
		// will be responsible for deleting the widget, so something like the
		// following can be used to support this:
		// if( self->parent() ) DaoCdata_SetData( self->dao_cdata, NULL );
		 
		// To avoid the deallocator of Dao_ClassTwo being called by the GC:
		self->dao_cdata = NULL;
	}
}
@[code(cxx)]


The remaining part for wrapping @[cyan]ClassTwo@[cyan] should be something like,
@[code(cxx)]
static void dao_ClassTwo_ClassTwo( DaoProcess *proc, DaoValue *p[], int n )
{
	Dao_ClassTwo *self = new Dao_ClassTwo();
	DaoProcess_PutValue( proc, (DaoValue*) self->dao_cdata );
}
static DaoFuncItem ClassTwoMethods[] =
{
	{ dao_ClassTwo_ClassTwo,  "ClassTwo()" },
	{ NULL, NULL }
};
static void Dao_ClassTwo_Delete( void *self )
{
	delete (Dao_ClassTwo*) self;
}
static void* Dao_ClassTwo_Cast_ClassOne( void *data, int down )
{
	if( down ) return static_cast<ClassTwo*>((ClassOne*)data);
	return dynamic_cast<ClassOne*>((ClassTwo*)data);
}
// The type information structure for ClassTwo:
static DaoTypeBase ClassTwo_Typer = 
{
	"ClassTwo", NULL, NULL, ClassTwoMethods,
	{ & ClassOne_Typer, NULL },
	{ Dao_ClassTwo_Cast_ClassOne, NULL },
	Dao_ClassTwo_Delete, NULL
};
// The Dao type structure for ClassTwo:
DaoType *dao_type_ClassTwo = NULL;

int DaoOnLoad( DaoVmSpace *vmSpace, DaoNamespace *nspace )
{
	...
	// Wrap ClassTwo as an opaque C/C++ type:
	dao_type_ClassTwo = DaoNamespace_WrapType( nspace, & ClassTwo_Typer, 1 );
	return 0;
}
@[code(cxx)]




@[section]
Data Conversion between Dao and C/C++
@[section]

Dao provides various C interface functions to make data conversion between Dao
and C/C++ simple. For simple data types, one can use the one of the following
functions to convert Dao values to C values,
@[code(cxx)]
daoint    DaoValue_TryGetInteger( DaoValue *self );
float     DaoValue_TryGetFloat( DaoValue *self );
double    DaoValue_TryGetDouble( DaoValue *self );
complex16 DaoValue_TryGetComplex( DaoValue *self );
char*     DaoValue_TryGetMBString( DaoValue *self );
wchar_t*  DaoValue_TryGetWCString( DaoValue *self );
DString*  DaoValue_TryGetString( DaoValue *self );
int       DaoValue_TryGetEnum( DaoValue *self );

void*     DaoValue_TryGetCdata( DaoValue *self );
void**    DaoValue_TryGetCdata2( DaoValue *self );
void*     DaoValue_TryCastCdata( DaoValue *self, DaoType *totype );
@[code(cxx)]
If the @[green]DaoValue@[green] object is of the requested type, the correct data
will be returned, otherwise zero or a null pointer is return.
The last three functions are execlusively for wrapped C/C++ types,
we come to this later.


For other data types, you may need to cast @[green]DaoValue@[green] objects
to proper types, and then use proper methods to retrieve C data values.
There are two ways to cast from @[green]DaoValue@[green] to other types,
one is to use @[green]DaoValue_Type()@[green] to check its type and than do C casting,
the other is to use one of the @[green]DaoValue_CastXXX()@[green] series of methods.
For example, the following are the two ways to cast @[cyan]value@[cyan] 
from @[green]DaoValue@[green] to @[green]DaoTuple@[green],
@[code(cxx)]
DaoTuple *tup1 = DaoValue_Type( value ) == DAO_TUPLE ? (DaoTuple*) value : NULL;
DaoTuple *tup2 = DaoValue_CastTuple( value );
@[code(cxx)]
@[green]DaoValue_CastXXX()@[green] methods will return NULL, if the value
is not the correct type.


@[text]
