\input texinfo   @c -*-texinfo-*-
@c %**start of header
@setfilename guile-gnome-corba.info
@settitle Guile-GNOME: CORBA
@c %**end of header

@copying 
This manual is for Guile-GNOME: CORBA (version 2.16.0, updated 12 June 2008)

Copyright 2001,2003,2004,2008 Free Software Foundation

@quotation 
Permission is granted to copy, distribute and/or modify this document under the
terms of the GNU General Public License, Version 2 or any later version
published by the Free Software Foundation.

@end quotation

@end copying

@dircategory The Algorithmic Language Scheme
@direntry 
* Guile-GNOME: CORBA: (guile-gnome-corba.info).  Remote objects with CORBA in Scheme.
@end direntry

@titlepage 
@title Guile-GNOME: CORBA
@subtitle version 2.16.0, updated 12 June 2008
@author Andy Wingo (@email{wingo at pobox.com})
@author Martin Baulig (@email{baulig at suse.de})
@page 
@vskip 0pt plus 1filll
@insertcopying 
@end titlepage

@ifnottex 
@node Top
@top Guile-GNOME: CORBA
@insertcopying 
@menu 
* gnome corba::          The CORBA wrapper
* gnome corba primitives::  Primitive functions
* gnome corba types::    Primtive types

* Function Index::       
@end menu

@end ifnottex

@iftex 
@shortcontents 
@end iftex

@node gnome corba
@chapter (gnome corba)
@section Overview
A CORBA wrapper for Guile.

@section Opening CORBA modules
@code{(gnome corba)} allows full integration between Scheme and remote CORBA
objects. However, the problem is how to get type information about these remote
objects -- it's not very useful to have an opaque @code{<CORBA:Object>} in
Scheme. It's also not very useful if you can't write your own CORBA servants in
Scheme.

Basically, there are two ways to solve this problem. You can parse the type's
interface description language (IDL) at runtime, or you can get the necessary
information from some other source. @code{(gnome corba)} does the latter, via
so-called "imodules".

Imodules are a feature of ORBit2, the ORB used in GNOME. ORBit2 is a CORBA
2.4-compliant Object Request Broker (ORB), which is of course interoperable with
other ORB implementations. An imodule is a shared library, installed as
@code{$(libdir)/<modulename>_imodule.la}. To create such a library for your own
IDL, you need to run ORBit2's IDL compiler, @code{orbit-idl}, with the
@option{--imodule} argument. See the @code{demos/corba/} directory in this
distribution for an example.

As an example, the rest of this section will refer to the sample IDL which can
be found in @code{demos/corba/Foo.idl} in this distribution.

Once you have installed the @code{Foo} CORBA library (including its imodule),
you can load its type information into Scheme by calling:

@example 
 (corba-primitive-open-module "Foo")
 
@end example

As a side effect, this call will define all of the GOOPS classes and methods
associated with the @code{Foo} module.

If there is a CORBA interface @code{Foo::Hello},
@code{corba-primitive-open-module} will create a GOOPS class @code{<Foo:Hello>}
which serves as stub class and another GOOPS class @code{<POA:Foo:Hello>} which
serves as skeleton class.

All stub classes are derived from @code{<CORBA:Object>} and their CORBA class
hierarchy is preserved in Scheme.

All skeleton classes are derived from @code{<PortableServer-ServantBase>} and
their CORBA class hierarchy is preserved as well.

@section Calling CORBA Methods
To call a CORBA method, all you need to do is to invoke the corresponding method
in the stub class. Let's assume @code{hello} is an instance of the
@code{<Foo:Hello>} class. We may invoke the @code{Foo::Hello::doHello} method
directly, in a most Schemely fashion:

@example 
 (Foo:Hello:doHello hello)
 
@end example

So to call CORBA methods, you don't even need to know that it's CORBA.

If a CORBA exception is signalled, a Scheme error will be thrown to the key
@code{corba-system-exception} or @code{corba-user-exception}, as appropriate.

@section Implementing CORBA servants
The interesting part is to implement CORBA servants in Scheme. Let's assume you
want to write a servant for the @code{Foo::Hello} interface.

The first thing you need to do is to derive its POA class

@example 
 (define-class <hello> (<POA:Foo:Hello>))
 
@end example

Then, you define methods:

@example 
 (define-method (Foo:Hello:doHello (hello <hello>))
   (display (list "Hello World!" hello)) (newline))
 
@end example

If you call @code{(next-method)}, the POA class' method will be run, which by
default will throw a @code{CORBA::NO_IMPLEMENT} system exception.

However, you can override this:

@example 
 (define-method (Foo:Bar:Baz:haveFun (object <POA:Foo:Bar:Baz>) a b)
   (display (list "Default Foo:Bar:Baz:haveFun handler!" a b))
   (newline))
 
@end example

If you created all the methods, you can create servants and call
@code{corba-servant->reference} to get a @code{CORBA::Object} reference:

@example 
 (define servant (make <hello>))
 (define hello (corba-servant->reference servant))
 
@end example

Now you have a CORBA Object @code{hello}, and can invoke methods on it:

@example 
 (Foo:Hello:doHello hello)
 
@end example

Although this looks like a normal Scheme procedural application, this is a
"real" CORBA call: @code{hello} is a "normal" CORBA Object.

Note of course that any CORBA Objects which you create in Guile are "owned" by
Guile's garbage collector, so make sure to @code{CORBA_Object_duplicate()} in a
C function before you store it somewhere.

@section Multiple inheritance
Like in C, you can also create servants for CORBA interfaces which are derived
from other interfaces:

@example 
 (define-class <maximum> (<hello> <POA:Foo:MaximumHello>))
 (define-method (Foo:Hello:doHello (hello <maximum>))
   (display (list "Hello Maximum World!" hello))
   (newline)
   (next-method))

 (define maximum-servant (make <maximum>))
 (define maximum (corba-servant->reference maximum-servant))
 
@end example

This creates a new servant for the CORBA interface @code{Foo::MaximumHello}
which is derived from @code{Foo::Hello} and @code{Foo::Bar::Baz}. This
inheritance is reflected in Scheme.

@example 
 ;; Calls method `Foo:Hello:doHello' in class <maximum> and then
 ;; in <hello> because of the (next-method).
 (Foo:Hello:doHello maximum)

 ;; Calls method `Foo:Bar:Baz:haveFun' in class <POA:Foo:Bar:Baz>,
 ;; the default handler.
 (Foo:Bar:Baz:haveFun maximum 1 2)
 
@end example

Since we're using real CORBA calls, all of this also works for calls which are
coming "from the outside", i.e. from C or from a remote process.

@section An important limitation
CORBA servants can be implemented either in C or in Scheme, but you cannot mix
them.

For example, in the example above, you learned how to create a CORBA servant for
the @code{Foo::MaximumHello} CORBA interface in Scheme. Now let's assume you
already have an implementation for the @code{Foo::Hello} interface in C.

Even if @code{Foo::MaximumHello} is derived from @code{Foo::Hello}, you cannot
use the @code{Foo::Hello} C implementation in Scheme.

This limitation may sound obvious, but it's not so obvious at all if you're a
bit familiar with CORBA. In C, you would normally expect to have a @code{vepv}
and a @code{epv} vector in a CORBA servant, and to be able to poke around in the
vepv to override methods.

As an ORBit2 specific implementation detail, servants which you create from
Scheme don't have a @code{vepv} at all and the @code{epv} is not what you'd
expect -- the @code{epv} entries are Scheme vectors and not pointers to C
functions.

@section CORBA structs / sequences
There is also support to access CORBA structs / sequences from Scheme, including
a special record type for structs. See the source code for details.

@section Usage
@anchor{gnome corba <CORBA:Object>}@deftp Class <CORBA:Object>
@end deftp

@anchor{gnome corba <PortableServer-ServantBase>}@deftp Class <PortableServer-ServantBase>
@end deftp

@anchor{gnome corba corba-record-type-vtable}@defvar corba-record-type-vtable
@end defvar

@anchor{gnome corba bonobo-get-object}@deffn Primitive bonobo-get-object moniker class
@end deffn

@anchor{gnome corba bonobo-object-query-interface}@deffn Primitive bonobo-object-query-interface object class
@end deffn

@anchor{gnome corba corba-servant->reference}@deffn Primitive corba-servant->reference servant
@end deffn

@anchor{gnome corba corba-record-accessor}@defun corba-record-accessor rtd field-name
@end defun

@anchor{gnome corba corba-record-constructor}@defun corba-record-constructor rtd . opt
@end defun

@anchor{gnome corba corba-record-constructor-from-struct}@defun corba-record-constructor-from-struct rtd
@end defun

@anchor{gnome corba corba-record-modifier}@defun corba-record-modifier rtd field-name
@end defun

@anchor{gnome corba corba-record-predicate}@defun corba-record-predicate rtd
@end defun

@anchor{gnome corba corba-record-type-descriptor}@defun corba-record-type-descriptor obj
@end defun

@anchor{gnome corba corba-record-type-fields}@defun corba-record-type-fields obj
@end defun

@anchor{gnome corba corba-record-type?}@defun corba-record-type? obj
@end defun

@anchor{gnome corba corba-record-typecode}@defun corba-record-typecode obj
@end defun

@anchor{gnome corba corba-record?}@defun corba-record? obj
@end defun

@anchor{gnome corba corba-sequence->list}@defun corba-sequence->list sequence
@end defun

@anchor{gnome corba corba-struct->record}@defun corba-struct->record struct
@end defun

@anchor{gnome corba gnome-corba-error}@defun gnome-corba-error format-string . args
@end defun

@anchor{gnome corba make-corba-record-type}@defun make-corba-record-type typecode . opt
@end defun

@node gnome corba primitives
@chapter (gnome corba primitives)
@section Overview
A CORBA wrapper for Guile.

@section Usage
@anchor{gnome corba primitives <CORBA:Object>}@deftp Class <CORBA:Object>
@end deftp

@anchor{gnome corba primitives <PortableServer-ServantBase>}@deftp Class <PortableServer-ServantBase>
@end deftp

@anchor{gnome corba primitives corba-primitive-find-poa-class}@deffn Primitive corba-primitive-find-poa-class class
@end deffn

@anchor{gnome corba primitives corba-primitive-invoke-method}@deffn Primitive corba-primitive-invoke-method method_name imethod class args
@end deffn

@anchor{gnome corba primitives corba-primitive-main}@deffn Primitive corba-primitive-main 
@end deffn

@anchor{gnome corba primitives corba-primitive-make-poa-instance}@deffn Primitive corba-primitive-make-poa-instance class
@end deffn

@anchor{gnome corba primitives corba-primitive-open-module}@deffn Primitive corba-primitive-open-module name
@end deffn

@anchor{gnome corba primitives corba-primitive-register-interface}@deffn Primitive corba-primitive-register-interface name
@end deffn

@anchor{gnome corba primitives corba-primitive-typecode->class}@deffn Primitive corba-primitive-typecode->class type
@end deffn

@anchor{gnome corba primitives corba-typecode-primitive->name}@deffn Primitive corba-typecode-primitive->name typecode
@end deffn

@anchor{gnome corba primitives corba-typecode-primitive?}@deffn Primitive corba-typecode-primitive? typecode
@end deffn

@node gnome corba types
@chapter (gnome corba types)
@section Overview
A CORBA wrapper for Guile.

@section Usage
@anchor{gnome corba types %corba-sequence-vtable}@defvar %corba-sequence-vtable
@end defvar

@anchor{gnome corba types %corba-sequence-vtable-offset-printer}@defvar %corba-sequence-vtable-offset-printer
@end defvar

@anchor{gnome corba types %corba-sequence-vtable-offset-user}@defvar %corba-sequence-vtable-offset-user
@end defvar

@anchor{gnome corba types %corba-struct-vtable}@defvar %corba-struct-vtable
@end defvar

@anchor{gnome corba types %corba-struct-vtable-offset-printer}@defvar %corba-struct-vtable-offset-printer
@end defvar

@anchor{gnome corba types %corba-struct-vtable-offset-user}@defvar %corba-struct-vtable-offset-user
@end defvar

@anchor{gnome corba types corba-object-class->typecode}@deffn Primitive corba-object-class->typecode class
@end deffn

@anchor{gnome corba types corba-sequence-length}@deffn Primitive corba-sequence-length corba_sequence
@end deffn

@anchor{gnome corba types corba-sequence-ref}@deffn Primitive corba-sequence-ref corba_sequence index
@end deffn

@anchor{gnome corba types corba-sequence-set!}@deffn Primitive corba-sequence-set! corba_sequence index value
@end deffn

@anchor{gnome corba types corba-sequence-set-length!}@deffn Primitive corba-sequence-set-length! corba_sequence length
@end deffn

@anchor{gnome corba types corba-sequence-type}@deffn Primitive corba-sequence-type corba_sequence
@end deffn

@anchor{gnome corba types corba-struct-fields}@deffn Primitive corba-struct-fields typecode
@end deffn

@anchor{gnome corba types corba-struct-is-a?}@deffn Primitive corba-struct-is-a? corba_struct typecode
@end deffn

@anchor{gnome corba types corba-struct-ref}@deffn Primitive corba-struct-ref corba_struct index
@end deffn

@anchor{gnome corba types corba-struct-set!}@deffn Primitive corba-struct-set! corba_struct index value
@end deffn

@anchor{gnome corba types corba-struct-type}@deffn Primitive corba-struct-type corba_struct
@end deffn

@anchor{gnome corba types corba-struct?}@deffn Primitive corba-struct? corba_struct
@end deffn

@anchor{gnome corba types corba-typecode->gtype-class}@deffn Primitive corba-typecode->gtype-class typecode
@end deffn

@anchor{gnome corba types make-corba-sequence}@deffn Primitive make-corba-sequence typecode num_tail_elts init_smob
@end deffn

@anchor{gnome corba types make-corba-struct}@deffn Primitive make-corba-struct typecode num_tail_elts init_struct
@end deffn

@anchor{gnome corba types gnome-corba-error}@defun gnome-corba-error format-string . args
@end defun

@node Function Index
@unnumbered Function Index
@printindex fn
@bye
