On 18-Apr-1999, Rob Browning <[EMAIL PROTECTED]> wrote:
> 
> Anyway, this means that no matter what, we're going to have to have
> separate specifications for our script exported functions.  We can't
> use SWIG or G-wrap directly on our headers.  I do have a way to do
> this (that I'll describe later) that's not too onerous and avoids the
> C/scripting API skew problem, but I'll get to that later.  One
> advantage to not just processing everything is that we have much more
> control over what gets exported, and can even take over the export of
> some functions manually when that's beneficial (more on that later).

Once you start having to specially define C functions for export, you
have really got to ask whether it might not be simpler to just use
something like CORBA to generate external interfaces.  Then people can
use their favourite language that has a CORBA interface.  Even EMACS
has a CORBA interface.

With CORBA you have to write special interface files anyway.  The only
difficult part is that there's not great support for CORBA and C under
Linux (the ORB that is in GNOME supports C, but I'm not sure how
advanced it is.  Omniorb supports C++ and is pretty good).  This would
have to be investigated.

CORBA will generate stubs and skeletons which you just fill in with
code that calls the appropriate gnucash functions.  It generates
function prototypes and some of the wrapper code to call them, and
it generates data structures which you convert your internal data
structures into.  It will do this at either end, and it's language
independent.

Is there a guile binding for CORBA?  I'd be surprised if there isn't,
but I guess we need to consider if it is mature enough.

> and lets presume that bar is an input parameter only (and is never
> used by foo after the invocation), and that baz is an output parameter
> only.  You can tell SWIG about this (at least on it's perl side, I'm
> not sure the guile module knows how to handle this) like this:
> 
>   void foo(const char *INPUT, double *OUTPUT);

In CORBA variables are input, output, or both.  I'm pretty sure
inter-language memory management is a lot better defined in CORBA.

> But this is going to require a large number of modifications to our
> code, and a large number of new types.  It definitely makes things
> uglier (in some sense) from the C side.

Actually, you can do it all by defining an external interface, and
just creating wrapper functions that convert the internal types and
representations into the external ones.

> Now in this whole process, I investigated G-wrap which is a
> guile/RScheme wrapper generator, and I discovered that it is in some
> ways a superior solution.  It's much lighter weight than SWIG, and I
> can easily stick the entire thing in ./lib, but it would only support
> scheme.  This is probably a deal breaker.  I *might* be happy with
> making that restriction, but I think the horse is already out of the
> barn.  We're already using things like ePerl which require the perl
> interface...
> 
> One of the nice things about G-wrap is that it allows you to specify
> what should be done with each individual function instead of just
> alowing you to talk about global types (like SWIG).  So you can say:
> 
>   (new-function
>    'shutdown
>    'void "gnc_shutdown" '((int exit_status)) "shuts down gnucash")
> 
> And it's more or less obvious exactly what you mean.  Or in the
> strings case:
> 
>   (new-function
>    'foo
>    'void "foo" '((const-string bar) (const-string baz)) "frotzes bar")
> 
> It also makes the function documentation availble from within the
> interpreter and generates html docs.
> 
> 
> Summary conclusions:
> 
>   1) We can't run the script wrapper generator over our headers
>      directly anymore.
> 
>   2) Hence we're going to have to have a separate specification for
>      the exported functions.
> 
>   3) This separate specification should never get out of sync with the
>      C prototypes.
> 
>   4) If we do have a separate specification, it will be much easier to
>      use whichever wrapper generator we want.
> 
> Recommendation:
> 
> After spending too much time over the past day or so trying things
> out, here's what I propose:
> 
>   1) We support .scrx files where for any header foo.h, you can create
>      a corresponding foo.scrx (script export) file.  This file will
>      contain the exported function specifications for that header.
> 
>   2) The given header foo.h will #include "foo.scrx.h" which will be
>      automatically generated from foo.scrx and will contain the C
>      protoypes for the exported functions.
> 
>   3) foo.scrx.* will also be generated.  These files will contain the
>      data that SWIG or G-wrap (whichever we're using) need to generate
>      proper, non-leaking wrappers.
> 
>   4) The specifications in .scrx will look like this:
> 
>      (exported-function
>       'shutdown
>       'void "gnc_shutdown" '((int exit_status)) "shuts down gnucash")
> 
>      I've already got trivial guile programs that will generate the C
>      prototypes and the G-wrap specifications from these, so on the
>      guile side we're all set.
> 
>    5) We'll also support (as we can) fancier type specifications
>       describing Accounts, AccountGroups, etc, so that we get a nice
>       interface to these from the scripting language.
> 
>    6) This will also allow us to take manual control of the wrapping
>       of selected functions (if we like).  In some cases we can make a
>       much nicer guile (or perl) interface for a given function by
>       doing it by hand while relying on the wrapper generator(s) for
>       the bulk work.
> 
> I think this will work, and will give us what we want without too much
> suffering.  Initially I'm going to try to do all the work with SWIG.
> Then everyone (all the languages) benefit.  Although I may have to
> rely on others to get the details in languages other than guile right.
> I know enough about guile's C side API to know that I can get it right
> even if it gets tricky (which it may not), but I don't know about
> perl/python/tcl's.
> 
> If I don't hear any screams of discontent, I'll probably just do all
> this soon.
> 
> Thoughts?

Consider the CORBA approach seriously.  It solves much the same problems
you are worried about, and requires much the same work on the gnucash
end, but allows more than just guile <-> C interaction.  The GNOME
people are getting into CORBA in a big way so I'm sure it will gain
support under Linux.  The CORBA binding for a particular language will
handle all the issues under that language, so you don't have to worry
about doing anything but implementing the specification you design. 

-- 
The quantum sort: 
        while (!sorted) { do_nothing(); }
Tyson Dowd   <[EMAIL PROTECTED]>   http://tyse.net/
----- %< -------------------------------------------- >% ------
The GnuCash / X-Accountant Mailing List
To unsubscribe, send mail to [EMAIL PROTECTED] and
put "unsubscribe gnucash-devel [EMAIL PROTECTED]" in the body

Reply via email to