Using ROOT 5.32 standalone with VS2008 and saving canvas as image

Hello,
I am trying to save a canvas with a plot as image / svg, but with no success so far (always empty). I have compiled ROOT 5.32 with vs2008 (we can’t change the compiler for now) and successfully were able to run example code which uses text output only. Note that I don’t use a TApplication/TRInt instance, since we already have a GUI. But when I want to save plots as image I always get a blank white image. The code is as follows:

//Needed for plugin manager
TASImage dummy;
TImageDump dummy2;

gPluginMgr->AddHandler("TVirtualPS", "svg", "TSVG",	"Postscript", "TSVG()");
gPluginMgr->AddHandler("TImage", "*", "TASImage", "ASImage", "TASImage()");
gPluginMgr->AddHandler("TVirtualPS", "image", "TImageDump", "Postscript", "TImageDump()");

TCanvas *canvas = new TCanvas();
TF1 *plot = new TF1("plot", "sin(x)", 0, 6);		
plot->Draw();
canvas->Print("test.png");	
delete plot;
delete canvas;

I appreciate any help you can give me. If there is a way to display graphs etc. in a second window besides our GUI this would also be very helpful.

This is unrelated. You need a TApplication instance to process the ROOT events. And I don’t understand why you need the gPluginMgr related code…

This is from a bugreport: Link. I had the same error while testing histogram fitting. I merely applied the solution to the image saving. I use dynamic linking, but this should make no difference.

My impression so far is, that an TApplication instance is created from the root main routine on startup. Calling gSystem->ProcessEvents() has no effect.

Well, OK, I can’t try anyway…

which main routine? Do you start root.exe, or do you create your own standalone application?

The one from the libCore.dll entry point. I don’t use root.exe. I link the dlls into our application dynamically.

Then you need a TApplication instance…

I already tried

void ThreadFunctionRootGUI()
{
	TApplication *theApp = new TApplication("App", 0,0);
	theApp->Run();
	delete theApp;
}

as a separate thread, but all I get is

Error in <TApplication::TApplication>: only one instance of TApplication allowed

and yes, I checked with a breakpoint, it only gets called once. This is why I wrote the main entry point from libCore.dll already creates it.

Don’t create a separate thread, but add it in your main() like for example:

int main(int argc, char **argv)
{
   TApplication theApp("App", &argc, argv);

   /// Your code here

   theApp.Run();
   return 0;
}

see also the many examples in the $(ROOTSYS)/test directory

If I do this, our main loop will never be executed. Our whole application won’t work.

Why? Do you have an infinite loop in your code? Did you try to add a gSystem->ProcessEvents() in your loop? Something like:

int main(int argc, char **argv)
{
   TApplication theApp("App", &argc, argv);

   while(1) {
      /// Your code here


      gSystem->ProcessEvents()
   }

   return 0;
}

I can try this and see what happens.

Then I’m puzzled… And trying to fix your code by guessing what you are doing is a bit complicated…

Sry didn’t see your edit, I am trying it the other way around but doubt it works.

It does not make a difference whether I create the TApplication instance in the main routine from our application or not. Calling gSystem->ProcessEvents() in our main loop also has no effect. I am trying to dig further, but my suspicion is, that in the batch mode (it automatically is enabled) all the env variables are missing (I checked that, hence the gPluginMgr stuff) and thus probably besides other things all the fonts can’t be loaded. Sadly I could not find any documentation for this use case. This would make things much easier. I also tried setting windows ROOTSYS environment variable before posting here with no effect. The root.exe itself runs flawlessly and has env variables.

Which GUI are you using? How (where) did you set ROOTSYS? Did you also add %ROOTSYS%\bin in your PATH?

GUI Is is mostly custom drawn GDI stuff and windows controls. I tried setting the path with no effect. I set the environment vars via VS and verify it in the application with e.g. getenv(“PATH”). Basically it is like Lorenzo Moneta wrote in the bug report: “When using a static library, you don’t have ROOTSYS defined”.

gEnv->Print();
TString rootsys = gEnv->GetValue("ROOTSYS", (char*)0);

always is empty, despite getenv(“ROOTSYS”) returns the correct path. I checked that yesterday before I started posting here.

OK, I’m developing on Windows since many years, and I have no idea what could be wrong in your application. And as previously said, trying to sole your issue by guessing what you are doing is a bit complicated… Note also that ROOT v5.32 is quite old…

This is irrelevant. Are you sure to use static libraries? Did you build ROOT yourself?

I will try to create a new empty project and see what happens. If that works I can compare the differences.
I use the old 5.32 version, because 6.xx does not support vs2008 and I can’t change the compiler.

This is irrelevant. Are you sure to use static libraries? Did you build ROOT yourself?

No, as I wrote in my posts, I link them dynamically, but as I wrote in my second post, this should not make any difference (static or dynamic). Also I wrote in my first post, that I build it myself.