Structure Pointer Question

David Geary dmg at ssc-vax.UUCP
Tue Jul 12 04:17:44 AEST 1988


In article <391 at teletron.UUCP>, andrew at teletron.UUCP (Andrew Scott) writes:
> Now that my original question has been answered, I have another:
>
> Suppose that I've constrcuted a library of functions that operate on a
> "generic" data structure called 'struct message'.  This structure is an
> incomplete type; the library functions merely deal with pointers to this
> structure but not with the fields within.
>
> It is now permissible to use this library with different declarations of
> 'struct message' *in the same program*?  I'm not planning on converting
> between multiple kinds of "messages", I just want to have multiple modules
> in the program able to use the previously constructed library with data
> structures applicable to (and used in) only one module.
>
> My initial guess is that it would work, given that C requires all structure
> pointers to have the same format and provided that I compile the different
> modules of the program seperately (so that the compiler doesn't see the
> multiple declarations).

  Well, I went through this kind of thing a couple of years ago while
developing a "psuedo-object-oriented" system.  Here's how I implemented it:

  First, let's describe a "struct Object":

  struct Object {
                   int  Type;  
		   char *Name;
                   
		   struct Object  *Parent;
		   struct Object  *Next;
		   struct Object  *Previous;

		   OBJECT_UNION  objs;
                 };
  
  typedef struct Object OBJECT;

  Parent, Next, and Previous, as you can probably guess, are linkages in
a tree structure, where "Objects" are stored. (By the way, in my implementation
each node in the tree can have any number of children, each of which can
have any number of children, etc).  
  I've also included a Type field, and a name for each object.
  The OBJECT_UNION is:

  typedef union {
		   THIS_TYPE_OF_OBJECT   *this.id;
		   THAT_TYPE_OF_OBJECT   *that.id;
		   ANOTHER_TYPE_OBJECT   *another.id;
                }
		   OBJECT_UNION;

  Where, of course, THIS_TYPE_OF_OBJECT, THAT_TYPE_OF_OBJECT, etc. are
all typedefs of structures.

  Now, you can write routines to manipulate OBJECTs, without regard to
what member is "alive" in the union.  You can compile the routines,
and put them in a library.

  The only problem you run into is with allocation.  When you create a
"new type" of OBJECT, you have to change the definition of the
OBJECT_UNION:

  typedef union {
		  THIS_TYPE_OF_OBJECT  *this.id;
		  THAT_TYPE_OF_OBJECT  *that.id;
		  ANOTHER_TYPE_OBJECT  *another.id;
		  NEWLY_CREATED_OBJECT *new.id;     /* here's new one */
                }
		  OBJECT_UNION;

and, you must add code to a function that allocates OBJECTS.  Here's
an example of the allocation routine:

#define MALLOC(type,num)   (type *)malloc(sizeof(type)*num)

OBJECT *CreateObject(type,name)
  int type;
  char *name;
{
  OBJECT *new;

  if( new = MALLOC(OBJECT, 1); 
  {
    new->Type = type;
    new->Name = malloc(strlen(name) + 1);
    strcpy(new->Name, name);

    switch(type)
    {
      case THIS_TYPE_OF_OBJECT_ID:  
      
      new->objs->this.id = MALLOC(THIS_TYPE_OF_OBJECT, 1);
			   /* Allocate specifics of THIS_TYPE_OF_OBJECT here */
			   break;
      
      /* ADD CODE FOR "NEW" OBJECT HERE */ 
    }
  }
}

When you create a new type of OBJECT, you simply add another statement to
the switch.

  Well, I don't know how clear all of this is, it's about time for me
to get off (of work, that is) ;-).  However, it really is a powerful
tool - here's an example of some source I wrote for developing pop-up
menus:


/****  MenuExample.c:  

  This program demonstrates the use of "ObjectTrees".
  See the files:  ObjectsStandard.h, ObjectsUserDefined.h to see
  the definition of Menus and Menu Items.

  This file creates data structures for pop-up menus, and links
  the data structures in a tree structure.
****/

#include <stdio.h>
#include "ObjectTrees.h"

CreateMenus(Top)
  OBJECT *Top;
{
  ObjectStackPush(Top, MENU_OBJ_ID, "Project Menu");
  ObjectStackPush(Top, MENU_OBJ_ID, "Cut And Paste Menu");
  ObjectStackPush(Top, MENU_OBJ_ID, "Extras Menu");
} 

CreateProjectMenuItems(Top)
  OBJECT *Top;
{
  OBJECT *ObjectPointer = ObjectGetNamedChild(Top, "Project Menu"); 

  ObjectEnqueue(ObjectPointer, MENU_ITEM_OBJ_ID, "Read File");
  ObjectEnqueue(ObjectPointer, MENU_ITEM_OBJ_ID, "Write File");
  ObjectEnqueue(ObjectPointer, MENU_ITEM_OBJ_ID, "Delete File");
}

CreateCutAndPasteMenuItems(Top)
  OBJECT *Top;
{
  OBJECT *ObjectPointer = ObjectGetNamedChild(Top, "Cut And Paste Menu");
  
  ObjectAddChild(ObjectPointer, MENU_ITEM_OBJ_ID, 1, "Cut");
  ObjectAddChild(ObjectPointer, MENU_ITEM_OBJ_ID, 2, "Copy");
  ObjectAddChild(ObjectPointer, MENU_ITEM_OBJ_ID, 3, "Paste");
  ObjectAddChild(ObjectPointer, MENU_ITEM_OBJ_ID, 4, "Clear Buffer");
}

CreateExtrasMenuItems(Top)
  OBJECT *Top;
{
  OBJECT *ObjectPointer = ObjectGetNamedChild(Top, "Extras Menu");

  ObjectAddChild(ObjectPointer, MENU_ITEM_OBJ_ID, 1, "Full Screen");
  ObjectAddChild(ObjectPointer, MENU_ITEM_OBJ_ID, 2, "Iconify");
  ObjectAddChild(ObjectPointer, MENU_ITEM_OBJ_ID, 3, "Import Graphics");
  ObjectAddChild(ObjectPointer, MENU_ITEM_OBJ_ID, 4, "High Resolution");
  ObjectAddChild(ObjectPointer, MENU_ITEM_OBJ_ID, 3, "Low Resolution");
}

main()
{
  OBJECT  *TreeTop = ObjectCreateTreeTop(), 
          *ObjectPointer,
          *ObjPoped,
          *ObjDequeued; 

  CreateMenus(TreeTop);
  CreateProjectMenuItems(TreeTop);
  CreateCutAndPasteMenuItems(TreeTop);
  CreateExtrasMenuItems(TreeTop);

  ObjectDoFunctionAllChildren(TreeTop, ObjectPrintPublicData);

  do 
    ObjPoped = ObjectStackPop(ObjectGetNamedChild(TreeTop, "Extras Menu"));
  while(ObjPoped);

  do
    ObjDequeued = ObjectDequeue(ObjectGetNamedChild(TreeTop, "Project Menu"));
  while(ObjDequeued);

  ObjectDoFunctionAllChildren(TreeTop, ObjectPrintPublicData);
}

The above functions create the data structures for menus, and link
them all together.

Note that I have added routines to treat the children of an object as
a stack or queue.

If you have any questions, send me some mail.



~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~	"... I live in hotels, tear up the walls."	~
~            I have accountants pay for it all.         ~ 
~							~
~                 Life's Been Good,			~
~                           Joe Walsh                   ~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

-- 
***********************************************************
* David Geary, Boeing Aerospace Co., Seattle, WA 	  *
* I disclaim all disclaimers....			  *
***********************************************************



More information about the Comp.lang.c mailing list