Win32 port
Havoc Pennington
hp at redhat.com
Sun Jun 25 11:10:33 PDT 2006
Hi,
Cool. Where is the string coming from on Windows? (Am I just missing
that part of the patch?) What I'm wondering is how does it get
allocated/freed.
There's a pretty good test suite in dbus so don't be afraid to rip 'er
up and refactor, in most cases breakage will be revealed by the suite.
There are maybe four kinds of opaque object in common use in
dbus/glib/gtk style C programming...
1. "allocated value objects"
Can be identified by the presence of _new(), _free(), optional
_copy() methods, passed around as a pointer (e.g. DBusMemPool,
DBusMutex, GHashTable, GError, GMarkupParseContext)
2. "true value objects"
Can be copied with C assignment operator and allocated on stack;
may have an _init() method but not _free() (e.g. DBusMessageIter,
DBusSHAContext, GtkTextIter, GdkColor)
3. "weird hybrid of 1 and 2"
The usage is to allocate on stack, _init(), then later _free();
using C assignment operator isn't allowed (e.g. DBusString,
DBusError, DBusUserInfo). I use this a lot in dbus, but it's
not used much in glib/gtk since #1 can always be used instead.
The main value of the "weird hybrid" is that you avoid a memory
allocation, which in most cases is silly overoptimization.
4. "refcounted object"
Similar to #1, but the object is reference counted rather than
having a flat free() method.[1] (e.g. GObject, DBusConnection)
I'd rather DBusUID fit into one of these patterns. If there's no memory
management on that windows UID, then you could use pattern #2, which
would look something like:
.h:
/* it's OK to copy this by value; it will never have allocated fields */
typedef struct {
void *dummy;
} DBusUID;
.c:
typedef struct {
union {
unsigned long unix;
char *windows;
} uid;
} DBusUIDReal;
void
_dbus_uid_init_unix(DBusUID *uid, unsigned long value)
{
DBusUIDReal *real = (DBusUIDReal*) uid;
_dbus_assert(sizeof(DBusUIDReal) <= sizeof(DBusUID));
real->uid.unix = value;
}
That would involve relatively few changes to code, though I'd still
rather pass it in to functions as "DBusUID *uid" and not "DBusUID uid"
to match the usual pattern.
If the Windows UID needs memory management though, you need to use
approach 1 or 3, approach 2 simply won't work. Either 1 or 3 is fine,
they are more or less equivalent and should be the same amount of work.
With 1 and 3 passing by pointer and not value is of course required
since C assignment isn't allowed.
btw, what about guid_t? What's up with that on Windows, should it get a
parallel/identical treatment?
Havoc
[1] Sub-rule for refcounted objects if you're interested; for language
binding reasons, public API objects have to be either immutable (so they
can be treated as a by-value object despite the refcount) or they have
to have "destroy notification" (so the language binding proxy can be
deleted on finalization)
More information about the dbus
mailing list