[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The only include file you need in both your client and server modules is `scf.h'. It contains a number of macros and functions that you will need for easier use of SCF. You will also have to add `scfimp.cpp' for both the server and the client, and `scf.cpp' for the client.
Some basic functionality of SCF is provided by a central object. It can
be accessed as `iSCF::SCF' and is of type `iSCF*' (which is also a
valid interface). This object can be accessed from anywhere, even from
dynamic libraries. It is used by several parts of SCF. Note that this
object is only available after calling scfInitialize()
, the main
initialization function of SCF.
To simplify things, all exported classes are supposed to be derived from some basical interface called `iBase'. Thus, any interface is supposed to implement some basical functionality. Currently `iBase' defines three interface functions:
void IncRef();
void DecRef();
iBase* QueryInterface(scfInterfaceID iInterfaceID, int iVersion);
To simplify things even more, `scf.h' provides several macros that provide default declarations and default implementations of these three methods. The `SCF_DECLARE_IBASE' macro will declare these three methods within any class definition that is derived from `iBase'. The `SCF_IMPLEMENT_IBASE' will add the default implementation of these function to your module. Example:
struct iTest : public iBase { ... }; class Test : public iTest { SCF_DECLARE_IBASE; }; SCF_IMPLEMENT_IBASE(Test) |
In reality, we need a few more macros because the QueryInterface()
function is not static--it depends on the interfaces implemented by given
object. In fact, SCF_IMPLEMENT_IBASE()
defines IncRef()
and
DecRef()
and the beginning of the QueryInterface()
function,
but not the end of that function (i.e. the closing brace). That's because you
have to use an additional macro called SCF_IMPLEMENTS_INTERFACE()
that
will add the code required to support all implemented interface inside the
QueryInterface()
:
SCF_IMPLEMENT_IBASE(Test) SCF_IMPLEMENTS_INTERFACE(iTest) SCF_IMPLEMENT_IBASE_END |
The `SCF_DECLARE_IBASE' macro also defines two member variables:
`scfRefCount' and `scfParent'. `scfRefCount' is the counter
for external references to this object and is used by IncRef()
and
DecRef()
methods. The `scfParent' variable points to the parent
object and is also used by IncRef()
and DecRef()
. Objects are
chained together in a tree-like fashion, and an call to IncRef()
will
also call scfParent->IncRef()
; same with DecRef()
. The root of
the chain is the class factory, that is, an object that is used to create
objects of a specific class. The object tree looks like this:
ClassFactory => Object => Embedded interface => Embedded interface => Sub-embedded interface |
Thus, if we call the IncRef()
method for Sub-embedded interface,
we also will increment reference count for Object and
ClassFactory.
You also should call SCF_CONSTRUCT_IBASE(parent)
inside your class
constructor, this macro will initialize `scfRefCount' to zero and
`scfParent' to parent. In fact, the constructor of any class
should receive at least one argument of type `iBase*' which should then
be passed along to the SCF_CONSTRUCT_IBASE()
macro.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |