[vtkusers] Mixing C++ and Tcl/Tk Code in vtk application

Daniel A. Mezentsev dan at barrt.ru
Sun May 5 21:12:44 EDT 2002


John Biddiscombe wrote:

> Daniel,
>
> In order to access your C++ created objects from tcl and your tcl created
> objects from C++, you're going to need to look carefully at the code in
> vtkTclUtil.cxx. Each time an object is created, you need to create an
> equivalent command in tcl to access it.
> If you look carefully at the vtkTclUtil code you should be able to see what
> you need to do.
>
> Here's a piece of code that I use...it accepts a vtkObject pointer and
> creates a tcl representation of it which can be queried by a tcl script
> running in the same program. This only covers creating the object. If you
> delete it from inside a script, or from C++, the copmmmand representing it
> needs to be deleted. This code is overkill but simulates an object created
> by a user in tcl - so it's fully interchangeable
>
> The following code assumes you are using the standard vtk tcl
> wrapping...(and that all the relevant vtkCommonInit, GraphicsInit,
> FilteringInit....etc have been initialized....)
>
> //--------------------------------------------------------------------------
> -
> int __fastcall TBvtkParam_TclWindow::InsertTclNewInstance(vtkObject *obj,
> Tcl_Interp *interp, char *name) {
>   //
>   // first get the command info for the object we're representing
>   //
>   Tcl_CmdInfo CommandData, cinf;
>   if (Tcl_GetCommandInfo(Interp, const_cast<char *>(obj->GetClassName()),
> &CommandData)!=1) {
>       throw("Internal problem creating Tcl vtkObject lookup");
>   }
>   // We need the CreateNewInstanceCommand from it (for the Object type)
>   vtkTclCommandStruct *cs = (vtkTclCommandStruct*)CommandData.clientData;
>   int (*TheInstanceNewCommand)(ClientData, Tcl_Interp *,int, char *[]) =
> cs->CommandFunction;
>   //
>   // Do some checks to make sure we're not treading on anything
>   //
>   vtkTclInterpStruct *is = vtkGetInterpStruct(interp);
>   // Make sure we are not duplicating a name
>   if (Tcl_FindHashEntry(&is->InstanceLookup,name)) {
>     throw Exception("Named Object Exists already");
>   }
>   // Make sure we are not clobbering a built in command
>   if (Tcl_GetCommandInfo(interp,name,&cinf)) {
>     throw Exception("A tcl/tk command with that name already exists.");
>   }
>   //
>   // Setup the internal Tcl Hash tables (!)
>   // 3 Hash tables : 1) Maps names of objects to actual raw pointers to
> objects
>   //                 1) Maps a string of the pointer to a string of the name
>   //                 1) Maps names of objects to their command structures
> (fn ptrs)
>   //
>   Tcl_HashEntry *entry;
>   int is_new;
>   // Create a hash entry : key=name, data=object
>   entry = Tcl_CreateHashEntry(&is->InstanceLookup, name, &is_new);
>   Tcl_SetHashValue(entry,(ClientData)obj);
>   // Create a hash entry : key=pointerstring, data=name
>   char temps[256];
>   sprintf(temps,"%p",(void *)obj);
>   entry = Tcl_CreateHashEntry(&is->PointerLookup, temps, &is_new);
>   Tcl_SetHashValue(entry,(ClientData)(strdup(name)));
>   // Create a hash entry : key=name, data=command function
>   entry = Tcl_CreateHashEntry(&is->CommandLookup,name,&is_new);
>   Tcl_SetHashValue(entry,(ClientData)(cs->CommandFunction));
>   //
>   // Create a new command to represent the (named) object
>   //
>   vtkTclCommandArgStruct *as = new vtkTclCommandArgStruct;
>   as->Pointer = (void *)obj;
>   as->Interp = interp;
>   Tcl_CreateCommand(interp, name, TheInstanceNewCommand, (ClientData)as,
> (Tcl_CmdDeleteProc *)vtkTclGenericDeleteObject);
>   //
>   // setup the delete callback
>   //
>   vtkCallbackCommand *cbc = vtkCallbackCommand::New();
>   cbc->SetCallback(vtkTclDeleteObjectFromHash);
>   cbc->SetClientData((void *)as);
>   as->Tag = obj->AddObserver(vtkCommand::DeleteEvent, cbc);
>   cbc->Delete();
>   //
>   return 1;
> }
> //--------------------------------------------------------------------------
> -
>
> You will almost certainly want to change the delete object callback to
> ensure that if the user deletes your object you can be alerted. The above
> code uses the default vtk callback which I've not changed here...
>
> JB
>
> vtk Based Contracts wanted...

John,

Sorry, I'm delayed.
At last days i'm study vtkTclUtil.cxx file very carefull.
I use vtkTclGetObjectFromPointer and vtkTclGetPointerFromObject functions for
my aim.

Thank You for suggestions.

With respect
Daniel.




More information about the vtkusers mailing list