Wize /
Loading
Search:  

Extern Loading

Following is an example of multi-level loading of a module. We start with the following module:

# File "math.tcl"
package require Mod

namespace eval ::myapp::math {

  Mod export

  proc add {i j} {#TYPES: . Double Double
    # Add two doubles together.
    return [expr {$i+$j}]
  }

  proc sub {i j} {#TYPES: . Double Double
    # Subtract two doubles.
    return [expr {$i-$j}]
  }

}

whose header file is:

# File "math.htcl"
package require Mod

namespace eval ::myapp::math {

  Mod export

  extern add {i j} {. Double Double}

  extern sub {i j} {. Double Double}

}

math is just one member of the myapp module:

# File "myapp.htcl"
package require Mod

namespace eval ::myapp {

  Mod export

  extern math {args} {} {D source $dir/math.htcl}

  ## Could have other sub-modules...
  #extern fill {args} {} {D source $dir/fill.htcl}
  #extern check {args} {} {D source $dir/check.htcl}
}

This would then be used as follows:

extern ::myapp {args} {} {D source $dir/myapp.htcl}
#...
puts [::myapp math add 9 10]

Compiled Extension

A module can easily be turned into a compiled extension. First define a C bodies include file:

# "File math.inc"
::app::math::add {
   Tcl_SetObjResult(interp, Tcl_NewDoubleObj(arg_i + arg_j));
}
::app::math::sub {
   Tcl_SetObjResult(interp, Tcl_NewDoubleObj(arg_i - arg_j));
}

Then run CAPI to generate main.c and compile:

  % capi math.tcl -impl math.inc
  Generated: Myappmath math.c
  % cc -shared -o libMyappmath.so math.c

Now tcl::loadextern will automatically load the shared library. If not available we fall back to the Tcl implementation.

NOTE: the library name is by default formed from the namespace using:

   string totitle [string map {:: {}} $namespace]

© 2008 Peter MacDonald

Page last modified on November 17, 2009, at 12:58 PM