I'm working on integrating c# and tcl 8.5. I'm able to use the
standard C interface to access the various TCL commands, however I'm
concerned about leaking memory on Tcl_Objs (Lists, Strings etc) that
I've 'created' in C# and then passed to the interpreter, for example
SetObjectResult.
I notice that I should be calling Tcl_IncrRefCount when I create the
object and Tcl_DecrRefCount when I'm done. However as these are
implemented as macro's I can't just import them into C#.
Is is just a case of converting the macro's into C# code to create the
same effect (with the possiblity of breaking forward compatibility) or
is there another method?
You might also write a small C stub defining them as functions (with a
slightly different name). The stub reuses the macros, so there is no
risk of incompatibility:
void func_Tcl_IncrRefCount(Tcl_Obj *obj) {Tcl_IncrRefCount(obj);}
-Alex
Tcl_SetObjResult will increment the reference count for you, so you
don't need to explicitly increment in this case. As a rule of thumb you
should always be able to match up Tcl_IncrRefCounts and
Tcl_DecrRefCounts in your source code. So, e.g. if you have code like:
Tcl_Obj *result = ...
Tcl_IncrRefCount(result);
Tcl_SetObjResult(interp, result);
return TCL_OK;
This should ring a bell as an error as there is no matching
Tcl_DecrRefCount. On the other hand, if you have a temporary Tcl_Obj
that you pass to several Tcl library calls:
Tcl_Obj *tmp = ...
Tcl_FooBar(tmp);
Tcl_BarFoo(tmp);
...
It should always be safe to wrap an incr/decr pair around this (and is a
wise thing to do):
Tcl_Obj *tmp = ...
Tcl_IncrRefCount(tmp);
Tcl_FooBar(tmp);
Tcl_BarFoo(tmp);
Tcl_DecrRefCount(tmp);
If you store a persistent reference to a Tcl_Obj then you should
*always* incr the count on store and decr on release.
-- Neil