Re: C++ in STk

From: Andrew Dorrell <>
Date: Wed, 16 Aug 95 10:34:33 EST

> I need to add some third party C++ code to STk *now*. I am not after a
> difinitive solution which addresses all the philosophical issues.... but
> would greatly appreciate knowing if and how other people have done this.

Thanks for the responses, here is a summary:

>From fox_at_GRAPHICS.CS.NYU.EDU Sat Aug 12 22:27:05 1995

I use C++ pretty much the way I would use C:

#include "stk.h"
#include "sys/time.h"

typedef PRIMITIVE (*PF)(...);

  struct timeval tv;
  gettimeofday(&tv, 0);
  return STk_cons(STk_makeinteger(tv.tv_sec), STk_makeinteger(tv.tv_usec));

class ZVector {
  ZVector(double x, double y);
  ZVector(const ZVector &p);
  double x() const;
  double y() const;
#if 0
  INLINE friend ZVector operator+(const ZVector &a, const ZVector &b);
  INLINE friend ZPoint operator+(const ZVector &a, const ZPoint &b);
  INLINE friend ZPoint operator+(const ZPoint &a, const ZVector &b);
  INLINE friend ZVector operator-(const ZVector &a);
  INLINE friend ZPoint operator-(const ZPoint &a, const ZVector &b);
  INLINE friend ZVector operator-(const ZVector &a, const ZVector &b);
  INLINE friend ZVector operator*(double k, const ZVector &a);
  INLINE friend ZVector operator*(const ZVector &a, double k);
  INLINE friend ZVector operator/(const ZVector &a, double k);
  INLINE friend double dot(const ZVector &a, const ZVector &b);
  INLINE friend double det(const ZVector &a, const ZVector &b);

  void operator*=(double k);

  ZVector cw90() const;
  ZVector ccw90() const;
  double lenlen() const;
  double length() const;
  double slope() const;
  bool operator==(const ZVector &v) const;
  double x_;
  double y_;

ZVector::ZVector(double x, double y) : x_(x), y_(y) {}
ZVector::ZVector(const ZVector &p) : x_(p.x_), y_(p.y_) {}

double ZVector::x() const {return x_;}
double ZVector::y() const {return y_;}

class ZVector;
#define TRVECTOR(x) ((ZVector*)(EXTDATA(x)))
#define TRVECTORP(x) (TYPEP(x, tc_trvector))
#define NTRVECTORP(x) (NTYPEP(x, tc_trvector))
extern int tc_trvector;
extern SCM make_vector(const ZVector &);

int tc_trvector;


free_tr_vector(SCM vector)
  delete TRVECTOR(vector);

static void
display_tr_vector(SCM vector, SCM port, int /*mode*/)
  ZVector *p = TRVECTOR(vector);
  sprintf(STk_tkbuffer, "[vector %.2f %.2f]", p->x(), p->y());
  Puts(STk_tkbuffer, FILEPTR(port));

static STk_extended_scheme_type tr_vector_type = {
  "trvector", /* name */
  0, /* is_procp */
  mark_tr_vector, /* gc_mark_fct */
  free_tr_vector, /* gc_sweep_fct */
  NULL, /* apply_fct */
  display_tr_vector /* display_fct */

make_vector(const ZVector &vector)
  SCM pinfo;
  NEWCELL(pinfo, tc_trvector);
  TRVECTOR(pinfo) = new ZVector(vector);
  return pinfo;

tr_make_vector(SCM x, SCM y)
  ZVector v(FLONM(x), FLONM(y));
  return make_vector(v);

tr_vector_x(SCM v)
  return STk_makenumber(TRVECTOR(v)->x());

tr_vector_y(SCM v)
  return STk_makenumber(TRVECTOR(v)->y());

extern "C" {

  STk_add_new_primitive("gettimeofday", tc_subr_0, (PF)stk_gettimeofday);

  tc_trvector = STk_add_new_type(&tr_vector_type);
  STk_add_new_primitive("tr:make-vector", tc_subr_2, (PF)tr_make_vector);
  STk_add_new_primitive("tr:vector-x", tc_subr_1, (PF)tr_vector_x);
  STk_add_new_primitive("tr:vector-y", tc_subr_1, (PF)tr_vector_y);

void STk_user_cleanup()


>From Sun Aug 13 04:06:20 1995

We've done some extensions to STk involving functions from the LibG++
Library using the String data type. Basically, we had to write a small
wrapper for each function which connects to STk. The wrapper adds an
argument which we called the class handle (void pointer to an object).
The STk primitive function then calls the wrapper using the class handle.
The wrapper, of course, call the C++ function.

Here's a concrete example for the LibG++ function String.freq which
counts the number of occurances of a substring within a String:
(see the LibG++ info pages for (a tiny bit) more info. (The LibG++
info pages really lack crucial information. :)).

The STk primitive looks like:

static PRIMITIVE freq(SCM string, SCM substring)
    int res;
    res = String_freq_char( (class_handle) new_String(CHARS(string)),
            CHARS(substring) );
    return(STk_makeinteger( (long) res));

This calls the wrapper String_freq_char. (Note that we need a different
wrapper for each combination of possible argument types - a drawback
of this method). The wrapper looks like:

int String_freq_char(class_handle h, char *ss) {
    return( ((String *) h)->freq(ss));

The class_handle is just a void *.

Of course, I'm glossing over some of the details, such as include
files and forward declaractions. I may also have some of the details
garbled since it was Sarah Officer (of our organization) who really
worked the details of this out. Anyway, hope that helps,

p.s. I don't know whether my mailer is gonna reply to you
     or stk-request. If you, feel free to repost this.

>From Mon Aug 14 23:37:20 1995

I incorporated stk into a linking loader (I didn't use the TK part, it
turned out). I changed the way the main loop worked a bit (C++ calls
something that calls stk that calls back into my C++ environment).
I'm 6 months out of the project, but I can certainly state that it can
be done and might be able to dredge up some details if that would


Mr Andrew Dorrell
School of Electrical Engineering                 *
University of Technology, Sydney                     *
PO Box 123                                     *
Broadway NSW 2007                                   .  
                                                    *       /---\  Whoo?
Phone:   61 2 330 2395                                      (o o) /
Fax:     61 2 330 2435                                      ( : )  
email:                               ^ ^     
Received on Wed Aug 16 1995 - 02:36:23 CEST

This archive was generated by hypermail 2.3.0 : Mon Jul 21 2014 - 19:38:59 CEST