<!--
  - Authors:
  -   Denys Duchier     <duchier@ps.uni-sb.de>
  -
  - Copyright:
  -   Denys Duchier, 1998
  -
  - Last change:
  -   $Date: 2000/10/12 15:17:15 $ by $Author: duchier $
  -   $Revision: 1.6 $
  -
  - This file is part of Mozart, an implementation
  - of Oz 3
  -    http://www.mozart-oz.org
  -
  - See the file "LICENSE" or
  -    http://www.mozart-oz.org/LICENSE.html
  - for information on usage and redistribution
  - of this file, and for a DISCLAIMER OF ALL
  - WARRANTIES.
  -
  -->
<chapter id=chapter.counter.global>
  <title/Global Counter Library/

  <p>Oz can be very simply extended with new functionality and
datatypes implemented in C or C++.  This capability is often used to
interface Oz to existing libraries: for example, the
<name type="library"/regex/ and <name type="library"/gdbm/ modules are
implemented in this fashion.</p>

  <p>Every extension is presented to the system in the form of a
<def/native functor/<index/functor<and>native/, &ie; a functor which
happens to be implemented in C or C++ rather than in Oz.</p>

  <p>In this chapter, we define a native functor that exports a
<code/<span class=ignore/ /next/
function which returns the next value of a global counter each time it
is called.</p>
  <section>
    <title/Implementation/
    <p><chunk class=ANONYMOUS><title/counter.cc/
#include "mozart.h"

static long n;

OZ_BI_define(counter_next,0,1)
{
  OZ_RETURN_INT(n++);
}
OZ_BI_end

OZ_C_proc_interface * oz_init_module(void)
{
  static OZ_C_proc_interface table[] = {
    {"next",0,1,counter_next},
    {0,0,0,0}
  };
  n = 1;
  return table;
}
</chunk>
<code/OZ_BI_define(counter_next,0,1)/ indicates that we are defining a
procedure <code/<span class=ignore/ /counter_next/ that implements a new builtin which
takes 0 input arguments and returns 1 output value. <code/OZ_BI_end/
is required to finish this definition.</p>

    <p><code/<span class=ignore/ /OZ_RETURN_INT(?{d})/ is a macro that causes
the builtin to return integer ?{d} as an Oz integer.  This should only
be used when the builtin has one unique output value; and it is essentially
equivalent to the code sequence:
<code display>
OZ_out(0)=OZ_int(d);
return PROCEED;
</code>
</p>

    <p>Finally procedure <code/<span class=ignore/ /oz_init_module/
implements the native functor: it performs
arbitrary initializations and then returns a table of builtins.  Each
entry in this table consists of (1) the name of the export, (2) the
input arity, (3) the output arity, (4) the procedure implementing the
builtin.  The table must be terminated by an entry whose fields are
all zero.</p>
    <p>Note that global variable <code/n/ is explicitly initialized by
<code/<span class=ignore/ /oz_init_module/ rather than with a static
initializer.  Here, it probably makes no difference, but you cannot in
general rely on the fact that constructors for global objects will be
properly invoked when the native functor is loaded.  What actually
happens varies from one system to another.  The only reliable
technique is to perform all initializations in
<code/<span class=ignore/ /oz_init_module/.</p>
    <p>You may also define the variable
<code/<span class=ignore/ /oz_module_name/ to give your native module a
name that can be used when printing the builtins which it exports.  This
is particularly useful for debugging and for interactively looking at
values.  For example,  you could give it the name <code/"GlobalCounter"/:
<code display/
char oz_module_name[] = "GlobalCounter";/
  </section>

  <section id=section.counter.global.compilation>
    <title/Compilation/
    <p>We must now make this native module available as a
<em/shared object library/.  First we must compile it and create
<file/counter.o/:
<code display proglang=sh>oztool c++ -c counter.cc</code>
Then we must produce a platform specific shared object library:
<code display proglang=sh
>oztool ld counter.o -o counter.so-`oztool platform`</code>
You may find it useful to create a <file/Makefile/ of the form:
<code.extern display proglang=makefile to="mkfile.xmp">
</p>
    <p><code proglang=sh/oztool/<index/<code proglang=sh/oztool//
is a program that invokes
the facility named as its first argument with appropriate options.
For example, it is essential to invoke the same C++ compiler and with
the same &eg; code generation options as were used for building the Oz
emulator; otherwise it will not be possible to dynamically link your
library into a running Oz process.  Normally, the Oz emulator is
compiled without <em/run time information/ (option
<code proglang=sh/-fno-rtti/ for g++) and without support for C++ exceptions
(option <code proglang=sh/-fno-exceptions/ for g++).
<code proglang=sh/oztool c++/ automatically invokes the right
compiler with the right options.  <code proglang=sh/oztool/ is
documented in <ptr.extern to="ozdoc:tools" key="chapter.oztool">.</p>
    <p>Even more complicated is how to create a DLL from a
compiled object file: it varies depending on the system, compiler and
linker used.  Under Windows, the sequence of necessary incantations is
so arcane and highly magical, it could well endanger your sanity.
Fortunately <code proglang=sh/oztool ld/ automatically takes
care of the details.</p>
  </section>
  <section id=section.counter.global.compilation.deployment>
    <title/Deployment/
    <p>Normally, you will then place the resulting shared object file, e.g.
<file/counter.so-linux-i486/ on a Linux system, in an installation
directory; let's call it ?{install}.  If your site has several
platforms sharing one file system, then you can place all platform
specific shared object libraries that you create from
<file/counter.cc/ in the same ?{install} directory.  They all have
distinct names since the platform name is appended.</p>
    <p>In an Oz functor, you then write an import of the form:
<code display proglang=oz>Cnt at '?{install}/counter.so{native}'</code>
The <code/<span class=ignore/'/{native}<span class=ignore/'// suffix
indicates to the system that this denotes a native functor whose
platform independent basename is <file>?{install}/counter.so</file>.
The module manager dynamically links the appropriate platform specific
shared object library (by appending the platform specific extension to
the basename) and makes available the module it defines as the
value of <code proglang=oz/Cnt/.  The body of your functor can invoke
<code proglang=oz/{Cnt.next}/ to get the next value of the global
counter.</p>
    <p>In the emacs OPI, you can try this out immediately:
<code display proglang=oz
      >declare [M] = {Module.link ['?{install}/counter.so{native}']}</code>
</p>
  </section>
</chapter>

<!--
Local Variables:
mode: sgml
mode: auto-fill
sgml-default-dtd-file: "chapter.ced"
sgml-auto-activate-dtd: t
adaptive-fill-mode: nil
End:
-->
