In a header file of your C/C++ application or extension that includes the Tcl library, add these lines:
#include <tcl.h> ... #if ((TCL_MAJOR_VERSION < 8) || ((TCL_MAJOR_VERSION == 8) \ && (TCL_MINOR_VERSION == 0))) typedef struct Tcl_SavedResult { char *result; Tcl_FreeProc *freeProc; } Tcl_SavedResult; extern void Tcl_DiscardResult _ANSI_ARGS_((Tcl_SavedResult *)); extern void Tcl_RestoreResult _ANSI_ARGS_((Tcl_Interp *, Tcl_SavedResult *)); extern void Tcl_SaveResult _ANSI_ARGS_((Tcl_Interp *, Tcl_SavedResult *)); #endif
Somewhere in your program/library code, add these lines:
#if ((TCL_MAJOR_VERSION < 8) || ((TCL_MAJOR_VERSION == 8) \ && (TCL_MINOR_VERSION == 0))) void Tcl_SaveResult(Tcl_Interp *interp, Tcl_SavedResult *savedPtr) { char *result = Tcl_GetStringResult(interp); if (interp->freeProc == TCL_STATIC) { /* String might go away with another Tcl_Eval() call, so make a copy. */ int length = strlen(result); savedPtr->result = Tcl_Alloc(length + 1); strcpy(savedPtr->result, result); savedPtr->freeProc = TCL_DYNAMIC; } else { savedPtr->result = result; savedPtr->freeProc = interp->freeProc; /* We've taken responsibility for savedPtr->result, so make sure the interp doesn't free it for us. */ interp->freeProc = TCL_STATIC; } Tcl_ResetResult(interp); } void Tcl_RestoreResult(Tcl_Interp *interp, Tcl_SavedResult *savedPtr) { Tcl_SetResult(interp, savedPtr->result, savedPtr->freeProc); } void Tcl_DiscardResult(Tcl_SavedResult *savedPtr) { if (savedPtr->freeProc == TCL_DYNAMIC) { Tcl_Free(savedPtr->result); } else { (*savedPtr->freeProc)(savedPtr->result); } } #endif
There! Now you can call Tcl_SaveResult(), Tcl_RestoreResult(), and Tcl_DiscardResult() even if you happen to link against a pre-Tcl 8.1 library.
DKF: From Tcl 8.5 onwards, you should use Tcl_SaveInterpState() instead of Tcl_SaveResult() (as it handles the richer result dictionary). From Tcl 9.0 onwards, that will be the only supported API.