Tuesday, January 08, 2013

Interface between C and TCL : Case III

Extending TCL script by C functions. The C functions are compiled as dynamic loaded library and is called from within a TCL script. The script can be interpreted by a standard TCL shell.

The C library is listed below.

#include <stdio.h>
#include <tcl.h>

int my_cmd1 (ClientData cdata, Tcl_Interp *interp,
    int objc, Tcl_Obj *const objv[]) {
  printf("Hello, world!\n");
  return TCL_OK;
}

int my_cmd2 (ClientData cdata, Tcl_Interp *interp,
    int objc, Tcl_Obj *const objv[]) {
  printf("Hello, again!\n");
  return TCL_OK;
}

// The function name must matches the dynamic library name.
// With the first letter in capital form and a "_Init" postfix.
int My_cmd_Init (Tcl_Interp *interp) {

  if (Tcl_InitStubs(interp, TCL_VERSION, 0) == NULL)
    return TCL_ERROR;

  Tcl_CreateObjCommand(interp, "my_cmd1", my_cmd1,
      (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL );

  Tcl_CreateObjCommand(interp, "my_cmd2", my_cmd2,
      (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL );

  return TCL_OK;
}

To compile this file into a dynamic library (in Mac OS X 10.8.2), run the following line:

gcc -Wall -shared -o my_cmd.dylib my_cmd.c \
  -undefined dynamic_lookup -rdynamic

The expected output is:

$ tclsh
% load ./my_cmd.dylib
dlsym(0x7fb5dbe02360, My_cmd_SafeInit): symbol not founddlsym(0x7fb5dbe02360, My_cmd_Unload): symbol not founddlsym(0x7fb5dbe02360, My_cmd_SafeUnload): symbol not found
% my_cmd1
Hello, world!
% my_cmd2
Hello, again!
% exit

The "symbol not found" error can be safely ignore for this simple example.

No comments: