Path: utzoo!attcan!uunet!lll-winken!lll-tis!ames!mailrus!cornell!uw-beaver!fluke!ssc-vax!dmg From: dmg@ssc-vax.UUCP (David Geary) Newsgroups: comp.lang.c Subject: Re: Structure Pointer Question Keywords: You don't really *read* this line, do you? Message-ID: <2080@ssc-vax.UUCP> Date: 11 Jul 88 18:17:44 GMT Organization: Boeing Aerospace Corp., Seattle WA Lines: 210 In article <391@teletron.UUCP>, andrew@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#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.... * ***********************************************************