[GNC-dev] Troubles with a basic API integration

John Ralls jralls at ceridwen.us
Sun Nov 15 14:16:30 EST 2020

> On Nov 14, 2020, at 9:58 PM, F. Eugene Aumson <feaumson at gmail.com> wrote:
> Hi all,
> I'd like to follow the example shown at
> https://wiki.gnucash.org/wiki/Using_the_API, which demonstrates creating a
> transaction.  And I'd like to do it with a freshly-created Postgres backend.
> That tutorial starts from a point at which you've already got an `Account`,
> and therefore can easily get a `QofBook` from it, which gets passed to
> `xaccMallocTransaction()`.  However, I'm having trouble getting that far.
> I've got some code put together, which you can see here:
> https://github.com/feuGeneA/a-gnucash-integration/pull/2  This email is
> largely a copy/paste of the PR description there.  Feel free to reply here,
> and/or comment on code directly there, whatever works for you.  For the
> sake of completeness, I've attached my source and my debug logs to this
> email, but all of that is visible in the PR (source code in the PR itself,
> and logs in the CI runs (GitHub Checks)).
> Thank you in advance for any feedback!
> Gene
> -----
> I've got the GnuCash engine connecting to Postgres, but I'm not sure what
> to do next, and I've got errors:
> * One error is coming from the `qof_session_destroy()` routine, and it
> doesn't seem to make any sense at all.
>    - You can see this error in the output of the `ci/circleci:build` Check
> on the commit `Start and stop the engine`.
>    - Note the error message `qof session error message: (-484235720).
> func: qof_session_destroy`.
>        - This is coming from my own routine `qof_error_check()` at
> `a-gnucash-integration.cpp:11`, which in this case is being called from
> `a-gnucash-integration.cpp:49`.
>    - Note that `qof_session_get_error_message(session)` is returning an
> empty string, and `qof_session_get_error(session)` is returning a
> ridiculous value.
>    - Am I using these routines right?
> * Another error is coming from my attempt to get the session's book and
> seed an `Account` with it.
>    - See what I introduced in the commit `Get QofBook and create a root
> Account`.
>    - Below are the `ERROR` logs are being emitted.  You can see the full
> debug log in the `ci/circleci:build` Check on the commit.
> ```
> * 05:37:54 ERROR <gnc.engine> Account* xaccMallocAccount(QofBook*):
> assertion 'book' failed
> * 05:37:54 ERROR <GLib-GObject> g_type_instance_get_private: assertion
> 'instance != NULL && instance->g_class != NULL' failed
> * 05:37:54 ERROR <gnc.engine> void xaccAccountBeginEdit(Account*):
> assertion 'acc' failed
> ```
> It feels like I'm not using these routines properly.  Where am I going
> wrong?
> Other questions:
> * How do i properly do error checking? Is my `qof_error_check()` routine
> the right approach? What about for non-`qof_`-prefixed routines, eg
> `xaccMallocTransaction()` or `gnc_account_create_root()`?
> * When do i need to call `qof_session_save()` or `qof_session_load()`?
> * What else should I be aware of as I continue trying to connect the dots
> between what I have here and what's shown in the API tutorial?
> <a-gnucash-integration.cpp><qof_session_destroy.log><gnc_create_account_root.log>

You're getting a nullptr book from the session because that's what you passed to qof_session_new(). Allocate a new QofBook (qof_book_new()) and pass it to qof_session_new(). The session takes ownership, so you can just do qof_session_new(qof_book_new()) if you like.

Error checking depends on the function. QofSession does error checking the way it does to decouple it from the GUI; a few functions use GError; most return an error value, often nullptr. The small amount of pure C++ code uses exceptions. No, qof_error_check is not good code, if for no other reason than that error messages shouldn't go to std::cout. I think you're getting an int instead of the message text because overload resolution is failing on the second call to std::ostream&(const char*). You could try static_cast<const char*>(qof_session_get_error_message(session)) to help the compiler but you might need to make "qof session error message: " into a std:string.

You don't need to call either qof_session_save() when you're using a SQL backend, changes are written to the database as part of committing the object edit (e.g. xaccTransCommitEdit()). qof_session_begin() loads the session for you.

You should start by reading the API documentation at https://code.gnucash.org/docs/MAINT, but it's incomplete and you'll have to spend a fair amount of time studying the code.

Finally, a warning: We make *no* stability guarantees about the C/C++ API. It can change any time without notice and changes may or may not be documented. We do intend to change that policy for libgnucash once we complete the C++ conversion, but that is a long way off.

John Ralls

More information about the gnucash-devel mailing list