使用glib的gtype/gobject开发的gtk, gstreamer等,都离不开一个gtype, gobject.
//1,用指针数组,保存基础类型,即一些父类型
static TypeNode *static_fundamental_type_nodes[(G_TYPE_FUNDAMENTAL_MAX >> G_TYPE_FUNDAMENTAL_SHIFT) + 1] = { NULL, };
//2, 用散列表来保持所有的类型,包括父类型,子类型
static GHashTable *static_type_nodes_ht = NULL;
static_type_nodes_ht = g_hash_table_new (g_direct_hash, g_direct_equal);
它使用指针作为键值
如:
如果没有的话,保持在static_fundamental_type_nodes; 如果有父类的话,就保持到父类的子类数组中pnode->children[i] = type; 同时把这个新的type 插入到hash table中: g_hash_table_insert (static_type_nodes_ht, GUINT_TO_POINTER (node->qname), (gpointer) type); |
参考gobject_query.c
主要是把父子关系清晰的打印出来:
指针数组static_fundamental_type_nodes,存放了无父类的typenode;
所以只要循环这个指针数组,然后对基础typenode, 嵌套循环其子类,就可以了。
/* GObject - GLib Type, Object, Parameter and Signal Library * Copyright (C) 1998-1999, 2000-2001 Tim Janik and Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General * Public License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ #include <stdlib.h> #include <string.h> #ifdef HAVE_UNISTD_H #include <unistd.h> #endif #include <fcntl.h> #include <glib-object.h> #include <glib/gprintf.h> static GType root = G_TYPE_OBJECT; static void show_nodes (GType type, GType sibling, const gchar *indent) { static gchar *indent_inc = NULL; static guint spacing = 1; static gboolean recursion = TRUE; #define O_SPACE " " #define O_ESPACE "" #define O_BRANCH "+" #define O_VLINE "|" #define O_LLEAF "`" #define O_KEY_FILL "_" GType *children; guint i; if (!type) return; if (!indent_inc) { indent_inc = g_new (gchar, strlen (O_SPACE) + 1); *indent_inc = 0; strcpy (indent_inc, O_SPACE); } children = g_type_children (type, NULL); if (type != root) for (i = 0; i < spacing; i++) fprintf(stderr, "%s%s\n", indent, O_VLINE); fprintf(stderr, "%s%s%s%s", indent, sibling ? O_BRANCH : (type != root ? O_LLEAF : O_SPACE), O_ESPACE, g_type_name (type)); for (i = strlen (g_type_name (type)); i <= strlen (indent_inc); i++) fputs (O_KEY_FILL, stdout); fputc ('\n', stdout); if (children && recursion) { gchar *new_indent; GType *child; if (sibling) new_indent = g_strconcat (indent, O_VLINE, indent_inc, NULL); else new_indent = g_strconcat (indent, O_SPACE, indent_inc, NULL); for (child = children; *child; child++) show_nodes (child[0], child[1], new_indent); g_free (new_indent); } g_free (children); } void list_type_node_tree(void) { gint i; root = ~0; for (i = 0; i <= G_TYPE_FUNDAMENTAL_MAX; i += G_TYPE_MAKE_FUNDAMENTAL (1)) { const gchar *name = g_type_name (i); if (name) show_nodes (i, 0, ""); } }
g_type_init()后的type list, 以及父子关系:
id | `GInterface | `GTypePlugin | `gchar | `guchar | `gboolean | `gint | `guint | `glong | `gulong | `gint64 | `guint64 | `GEnum | `GFlags | `gfloat | `gdouble | `gchararray | `gpointer | `GType | `GBoxed | `GValueArray | `GParam | +GParamChar | +GParamUChar | +GParamBoolean | +GParamInt | +GParamUInt | +GParamLong | +GParamULong | +GParamInt64 | +GParamUInt64 | +GParamUnichar | +GParamEnum | +GParamFlags | +GParamFloat | +GParamDouble | +GParamString | +GParamParam | +GParamBoxed | +GParamPointer | +GParamValueArray | +GParamObject | +GParamOverride | +GParamGType | `GParamVariant | `GObject | `GVariant
| `void | `GInterface | +GTypePlugin | +GstChildProxy | `GstURIHandler | `gchar | `guchar | `gboolean | `gint | `guint | `glong | `gulong | `gint64 | `guint64 | `GEnum | +GstFormat | +GstPadDirection | +GstBufferListItem | +GstBusSyncReply | +GstClockReturn | +GstClockEntryType | +GstClockType | +GstState | +GstStateChangeReturn | +GstStateChange | +GstCoreError | +GstLibraryError | +GstResourceError | +GstStreamError | +GstEventType | +GstSeekType | +GstQOSType | +GstIndexCertainty | +GstIndexEntryType | +GstIndexLookupMethod | +GstIndexResolverMethod | +GstDebugLevel | +GstDebugColorFlags | +GstIteratorResult | +GstIteratorItem | +GstPadLinkReturn | +GstFlowReturn | +GstActivateMode | +GstPadPresence | +GstPluginError | +GstRank | +GstQueryType | +GstBufferingMode | +GstStreamStatusType | +GstStructureChangeType | +GstTagMergeMode | +GstTagFlag | +GstTaskState | +GstTypeFindProbability | +GstURIType | +GstParseError | +GstSearchMode | +GstProgressType | `GstCapsIntersectMode | `GFlags | +GstObjectFlags | +GstBinFlags | +GstBufferFlag | +GstBufferCopyFlags | +GstBusFlags | +GstCapsFlags | +GstClockFlags | +GstDebugGraphDetails | +GstElementFlags | +GstEventTypeFlags | +GstSeekFlags | +GstAssocFlags | +GstIndexFlags | +GstMessageType | +GstMiniObjectFlags | +GstPadLinkCheck | +GstPadFlags | +GstPadTemplateFlags | +GstPipelineFlags | +GstPluginFlags | +GstPluginDependencyFlags | +GstAllocTraceFlags | `GstParseFlags | `gfloat | `gdouble | `gchararray | `gpointer | `GType | `GBoxed | +GValueArray | +GstCaps | +GstStructure | +GstDate | +GstDateTime | +GDate | +GstBufferListIterator | +GstParseContext | `GError | `GParam | +GParamChar | +GParamUChar | +GParamBoolean | +GParamInt | +GParamUInt | +GParamLong | +GParamULong | +GParamInt64 | +GParamUInt64 | +GParamUnichar | +GParamEnum | +GParamFlags | +GParamFloat | +GParamDouble | +GParamString | +GParamParam | +GParamBoxed | +GParamPointer | +GParamValueArray | +GParamObject | +GParamOverride | +GParamGType | +GParamVariant | `GstParamFraction | `GObject | +GstObject | | | +GstPad | | | +GstPadTemplate | | | +GstPluginFeature | | | | | +GstElementFactory | | | | | +GstTypeFindFactory | | | | | `GstIndexFactory | | | +GstElement | | | | | `GstBin | | | | | `GstPipeline | | | +GstBus | | | +GstTask | | | +GstTaskPool | | | +GstClock | | | +GstPlugin | | | `GstRegistry | `GstSignalObject | `GVariant | `GstMiniObject | +GstQuery | +GstMessage | +GstBuffer | +GstEvent | `GstBufferList | `GstFourcc | `GstIntRange | `GstInt64Range | `GstDoubleRange | `GstFractionRange | `GstValueList | `GstValueArray | `GstFraction