Problem implementing a "manager" in a ParaView custom application

Not sure whether this is more a CMake or a Windows related problem, but first of all it happens with a custom application derived from ParaView.

In that application I need a singleton class, for some data that need to be accessible from “everywhere”. With dlls on Windows this is difficult to achieve the normal way (with some static elements in a class) because Windows will generate multiple instances even of the static data objects. However, in ParaView the different “managers” are doing exactly the same thing nicely.

My problem is now the access to my own “manager”: during link time (Windows) I get the message that the pqApplicationCore functions “instance()” and “manager()” are not found - which makes sense. With grep I see that they should be here:

$ grep -r --include *.lib pqApplicationCore
Binary file lib/vtkpqCore-pv5.6.lib matches

So I am using the following construct in my CMake file:

TARGET_LINK_LIBRARIES(MyModule PRIVATE vtkpqCore${PV_VER})

With this I am getting a complaint that it cannot find vtkpqCore.lib - as if PV_VER was “nothing”. Which it seems to be if I check with a MESSAGE statement.

BUT THEN:

But then I have a similar case in my software where I need to link to vtkCommonCore-pv5.6.lib that exists in exactly the same lib folder. And I do it in exactly the same way:

TARGET_LINK_LIBRARIES(OtherModule PUBLIC vtkCommonCore${PV_VER})

And this works perfectly! I can check with MESSAGE and see that also here PV_VER is empty. Kind of “magic” (!??) thus. And I can do the other test: drop that TARGET_LINK_LIBRARIES statement altogether - and the linker complains about missing functions, so it is not just dead code here.

Bottom line: IF I could really call pqApplicationCore::instance->manager(…) from EVERYWHERE in my program I would have my singleton. But I am not able to get the linkage properly done on Windows to make it happen!

Seems to be some nasty Windows thing though.

TWO FINDINGS so far:

  1. Tried the following in CMake script for some test module:

MESSAGE("PV_VER is " ${PV_VER})
TARGET_LINK_LIBRARIES(MyModule PUBLIC vtkpqCore${PV_VER} vtkCommonCore${PV_VER})

This shows:

a) PV_VER is empty at the point of the MESSAGE
b) the *.rsp file for the linker contains vtkpqCore.lib and vtkCommonCore-pv5.6.lib

-> the PV_VER is not just a variable that is expanded directly, but some other kind of “magic” is going on where the two libs are handled DIFFERENTLY.

  1. I looked for other parts of ParaView where pqApplicationCore::instance() is used, and looked into the SierraPlotTools. There I could not find any reference to that vtkpqCore library directly, and otherwise the only difference to my own code is that I am just generating an “ordinary library” with

ADD_LIBRARY(…)

while the SierraPlotTools is a plugin and is generated with

ADD_PARAVIEW_PLUGIN(…)

Could that be the difference somehow?

Maybe weird, but I am still struggling with that problem (for almost 12 hours now), and finally I gave it up and started to implement some kind of “divide and conquer” solution:

  1. first implement a plain C++ singleton class, with no VTK, PV or Qt stuff, and put it into a DLL, with the typical Windows botch with macros, __declspec and all that stuff. And make sure that I can load it from different points in my application - and basically pass one single value from one to the other.

THIS IS NOW WORKING - at least!

  1. try to make this single value a pointer to a class that I really need, like some kind of duplicate of what the pqApplicationCore class is doing with the “managers” (which I am not able to properly link into all my program parts - see problem description above)

  2. have this manager finally do all the data exchange jobs that I need now and in the future.

Not a nice design, but now that step 1 finally worked it might be easiest to follow up.

Note: With Qt I have a simplar problem with this DLL export like the above mentioned linking problem: there it seems to be more or less impossible to export - and then also IMPORT (!!) - a class that is derived from QObject. The reason is that the Q_OBJECT macro generates some code (with MOC) that is failing because of the __declspec(dllimport).

Bottom line: problem not solved, but a workaround looks at least somehow feasible now. I HOPE !

With the aid of some helpful person on a Qt forum I finally found a solution for my problem of not being able to generate a QObject based singleton in a Windows DLL:

Now with this solution at hand I can say that “somehow” also this current question is solved, or better: not any more relevant.

Because instead of using the “manager” facility of ParaView I can now generate singleton “manager” classes that are not plugged into that manager facility at all, so also no need to properly link to vtkApplicationCore.

At the same time also my previous workaround (a non VTK/PV/Qt singleton) is obsolete.

Solution: see the link above