[vtkusers] Can't execute point picking with following code
Obada Mahdi
omahdi at gmx.de
Sat Jul 14 07:36:57 EDT 2007
Hi Flo,
it looks like you just forgot to actually define the static member
variable "SimpleView::This":
Flo wrote:
> In a class SimpleView I have:
>
> public:
> static void Test(vtkObject* vtkNotUsed(object),unsigned long event,void*
> clientdata, void* vtkNotUsed(calldata));
>
> private:
> static SimpleView *This;
>
> and in the SimpleView constructor I declared:
> This=this
>
> Finally, in Test I do as follows:
>
> SimpleView::This->MouseMotion (also tried This->MouseMotion ) and same
> for iren, ren and picker
>
>
> BUT then during the linking process I have the following error:
> /usr/bin/ld: Undefined symbols:
> SimpleView::This
The declaration "static SimpleView *This;" within the class declaration
does not actually define (i.e. "reserve space") for that symbol, it just
announces its existence (that's why the compiler doesn't complain).
Just put a
| SimpleView *This = 0;
(without the "static" keyword) somewhere in your implementation -- .cc,
.cxx, or whatever extension you are using :-)
> On 10-Jul-07, at 7:33 AM, Luca Pallozzi Lavorante wrote:
>
>> Dear Flo, I have had a similar problem and the solution I adopted may
>> not be elegant but it works. Use a static attribute ( i.e., "This",
>> note the uppercase "T") that you can use in the callback. The
>> attribute is a pointer to a class PLUS. PLUS´s constructor would
>> initialize it to "this" (something like "This = this"). Another
>> solution would be to make static all the pointer attributes you need
>> to use in your callback (iren ren, picker and so on...). I also tried
>> this second path but I found it is a lit more messy.
Given that "SimpleView" is meant to be a true singleton design (i.e.
there is at most one living instance at any time), the solution with a
static pointer is perfectly fine, especially because there should be one
to record the only existing instance (if any) anyway.
There is a more general, slightly different technique for binding a
callback object (or function) to a particular instance, and VTK actually
offers a simple mechanism for doing this through the SetClientData()
method of vtkCallbackCommand. This "client data" simply is a single
void pointer, which is passed on to the callback function unmodified.
The idea is that you can define some kind of context for the callback
handler by setting up the "client data" pointer as you see fit upon
initialization of the callback object, and then use this context later
within the handler. In your case, Flo, you might just set up the
callback's client data to point to the SimpleView instance, and cast it
back appropriately in the static callback handler, just as you have done
it with the vtkInteractorStyle instance. Accessibility of the
interactor style instance is retained if passing on the SimpleView
instance instead, you can obtain it just as any other instance variable
of SimpleView.
In even larger or more complicated scenarios, it might be appropriate to
have a dedicated struct or class for recording necessary callback context.
HTH,
Obada
More information about the vtkusers
mailing list