John Ralls jralls at
Mon Oct 24 16:39:47 EDT 2011

On Oct 24, 2011, at 12:45 PM, Christian Stimming wrote:

> Am Montag, 24. Oktober 2011 schrieb John Ralls:
>>>  1. r21483 - gnucash/trunk/src/optional/gtkmm - [Gtkmm] Add
>>>     gnc::GncInstance as wrapper for QofInstance, to be used as a base
>>>     class for the derived qof classes. (Christian Stimming)
>>>  2. r21484 - gnucash/trunk - [Gtkmm] For unittests we only need
>>>     glibmm, not gtkmm. (Christian Stimming)
>>>  3. r21485 - gnucash/trunk - [Cutecash] Prepare cutecash for
>>>     integration of the glibmm wrappers of the engine objects.
>>>     (Christian Stimming)
>> Christian,
>> You're getting *way* ahead of me here. The engine classes aren't
>> implemented correctly as GObjects, so they're not suitable for wrapping
>> with glibmm
> Dear John,
> this should not be a contradiction at all. I'm trying to get to know how 
> glibmm works, and how wrapping a C GObject in C++ would work. As a usecase, 
> I'd like to use those glibmm wrapper classes in the cutecash experiment. The 
> previous C++ wrappers in cutecash are not at all correctly implemented as they 
> don't know about the destruction of the C object, but nevertheless cutecash 
> was already a usable application. Hence, I'd like to check whether the current 
> incomplete GObject implementation of the gnucash engine is already sufficient 
> to do some trivial GUI design in C++. This is why I'm committing this code.
>> , and while QofInstance is, the way it interdepends with
>> QofBook is bad. As part of rewriting engine to be correctly implemented
>> GObjects, a lot of QOF (QofClass, QofObject, and QofEvent so far) will go
>> away
> Sure. I've noticed the weird dependency between QofInstance and QofBook as 
> well, and indeed, this has to be solved differently in the long run. Also, I 
> completely agree the other QOF classes should rather go away. My intention was 
> to add glibmm wrappers for the "business logic classes", but not the others. 
> As it turned out this has to be the full set of Account / Split / Transaction 
> / Commodity / Numeric / Book, but that's about it.
>> -- but I'm months away from even starting on that, and it will
>> probably be 2 years before the branch can be merged back into trunk unless
>> I get some help.
>> Even then it won't be done, though, because I don't think QOF is going to
>> work as an object-relational map, so the class structure may well change
>> some more to move the querying into the back ends and to do most of the
>> computations with queries (because the only objects in memory will be the
>> ones currently displayed).
> Agreed as well. Again, this is done to learn about glibmm rather than to 
> implement some concept that must not be changed again. Instead, it is an 
> initial implementation to give us a better understanding when deciding about 
> the actual long-term plans.


Mostly OK, but the core engine classes don't construct or destroy via GObject. They have functions xaccMallocFoo and xaccFooDestroy which call other member object constructors/destructors, hand create and destroy the contents of the GLists in the QofCollections (another QOF class on death row) members, and eventually call g_object_new() or g_object_unref(). Totally fubar, especially since more than one collection can have pointers to e.g. Split objects, so destroying one has to be broadcast via QofEvent so that everything else that has a pointer can delete the reference. I doubt that you'll be able to do a clean representation in C++ until that's fixed up -- and you might well go mad trying! 

You *could* wrap directly by having C++ classes with a single member, the engine class, and calling the appropriate functions in the constructor and destructor of the C++ class, something like this:

class cppAccount {
    cppAccount (QofBook *book) {
        m_account = xaccMallocAccount (book);
   ~cppAccount () {
	xaccAccountDestroy (m_account);
//Other wrapped functions as needed...
  Account *m_account;

That's a lot of hand work, though, and I don't see much gain over just using the C API directly in your Qt Gui functions.

Some of the newer classes (Lots was one, IIRC) construct and destroy correctly through GObject (meaning that you can call g_object_new() and g_object_run_dispose() on them and they'll do the right thing). Maybe you could practice with one of them.

John Ralls

More information about the gnucash-devel mailing list