[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6.3.6 Example

Here is a completely working example. It implements a shared class that has a base and an embedded interface.

Here are the interface files for the `iDog' interface (the base interface of our class) and the `iName' interface (the interface embedded into our class).

File: `idog.h'

 
#include "csutil/scf.h"

// Version number of our interface.
SCF_VERSION(iDog, 0, 0, 1)

struct iDog : public iBase
{
  virtual void Walk() = 0;
  virtual void Shout(char const* iWhat) = 0;
};

File: `iname.h'

 
#include "csutil/scf.h"

// Version number of our interface.
SCF_VERSION(iName, 0, 0, 1);

struct iName : public iBase
{
  virtual char const* GetName() = 0;
  virtual void SetName(char const* iName) = 0;
};

Now here is the implementation of a class for both of the mentioned interfaces:

File: `dog.cpp'

 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "cssysdef.h"

#include "idog.h"
#include "iname.h"

class csDog : public iDog
{
  char* Name;

  // Embedded interface.
  class csName : public iName
  {
  public:
    SCF_DECLARE_EMBEDDED_IBASE(csDog);
    virtual char const* GetName();
    virtual void SetName(char const* iName);
  } scfiName;
  friend class csName;

public:
  SCF_DECLARE_IBASE;
  csDog(iBase* iParent);
  virtual void Walk();
  virtual void Shout(char const* iWhat);
};

//---------- Implementation ---------

SCF_IMPLEMENT_IBASE(csDog)
  SCF_IMPLEMENTS_INTERFACE(iDog)
  SCF_IMPLEMENTS_EMBEDDED_INTERFACE(iName)
SCF_IMPLEMENT_IBASE_END

csDog::csDog(iBase* iParent)
{
  SCF_CONSTRUCT_IBASE(iParent);
  SCF_CONSTRUCT_EMBEDDED_IBASE(scfiName);
  Name = 0;
}

void csDog::Walk()
{
  printf("%s: I'm walking\n", Name);
}

void csDog::Shout(char const* iWhat)
{
  printf("I'm %s: shout, shout, %s\n", Name, iWhat);
}

// iName interface for dog.

SCF_IMPLEMENT_EMBEDDED_IBASE(csDog::csName)
  SCF_IMPLEMENTS_INTERFACE(iName)
SCF_IMPLEMENT_IBASE_END

char const* csDog::csName::GetName()
{
  return scfParent->Name;
}

void csDog::csName::SetName(char const* iName)
{
  if (scfParent->Name)
    free(scfParent->Name);
  scfParent->Name = strdup(iName);
}

// Now export all classes.

SCF_IMPLEMENT_FACTORY(csDog)

SCF_EXPORT_CLASS_TABLE(Dog)
  SCF_EXPORT_CLASS(csDog, "csDog", "A Dog that shouts")
SCF_EXPORT_CLASS_TABLE_END

The above three files should be compiled together to get a shared library. The shared library should export the Create_csDog() function (implemented with the SCF_IMPLEMENT_FACTORY() macro). On most platforms this is achieved automatically, however on Windows you may need to write a `.def' file for this. Finally, here is the source code for a simple client application that uses the `csDog' class:

File: `doggy.cpp'

 
#include <stdio.h>

#include "cssysdef.h"

#include "csutil/scf.h"
#include "csutil/cfgfile.h"

#include "idog.h"
#include "iname.h"

int main ()
{
  csConfigFile config("scf.cfg");
  scfInitialize(&config);

  iDog *dog = SCF_CREATE_INSTANCE("csDog", iDog);
  if (!dog)
    fprintf(stderr, "No csDog shared class!\n");
  else
  {
    iName* name = SCF_QUERY_INTERFACE(dog, iName);
    if (!name)
      fprintf(stderr,
        "Dog does not support iName interface!\n");
    else
    {
      name->SetName("Droopy");
      dog->Walk();
      dog->Shout("hello!");
      printf("Dog's name is %s\n", name->GetName());
      name->DecRef();
    }
    dog->DecRef();
  }

  iSCF::SCF->Finish();
}

Now the last thing: SCF uses a file called `scf.cfg' for storing the class name to shared library name mapping. The file's format is simple: `ClassName = SharedLibraryName'. So, for the above example to work you have to add a line that reads `csDog = dog' to the [SCF.Registry] section of the configuration file `scf.cfg'.

Alternatively, you can register classes at run time:

 
iSCF::SCF->RegisterClass("csDog", "Dog");


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

This document was generated using texi2html