TExec in standalone compiled code?

I’d like to add some interactivity to some compiled standalone code that is linked against the ROOT libraies. Specifically I I want to use mouse clicks in a TPad to trigger execution of some code. So I started with the Dynamic.C example and I can do most of what I want within the ROOT interpreter . But I’m having difficulty porting it to compiled code : first of all there appears to be no way to pass the address of the equivalent of DynamicExec() ( the entry point of the code I want to trigger ) to the calling code. I’m informed at execution time that it doesn’t exist. Secondly, it seems the only way to pass arguments to DynamicExec() is via global storage and not as calling arguments - is this correct ? Thirdly, once I add a TExec to a TCanvas how do I remove it later on ?

And just to clear - the code draws a number of 2D histograms and drops into ROOT by setting TRint::Run to kTRUE when I want this to work. I suppose I could trigger another ROOT macro .C file but I’d ratehr have everything in a single piece of code

Is it impossible to do what I want to do or have I overlooked something ?

peter

Hello @peter.skensved,
thanks for reaching out!
First of all, can you provide a minimal code snippet that reproduces your situation? Can you specify how you are compiling your code? Can you also provide a link to the example Dynamic.C you’re mentioning? And last, could you provide information about your operation system and installed ROOT version?

Cheers,
Monica

Hi Monica,
I’m currently using 6.26.10 on Rocky Linux 8.8 ( ie. same as RedHat / CenOS ). The basic problem appears to be hat I can only pass addresses to AddExec in the the interpreter and not in compiled code . I’m attaching a slightly modified Dynamic.C example . To compile it as stand alone code I use this command :
g++ -g -o Dynamic1 -I $ROOTSYS/include $ROOTSYS/bin/root-config --glibs Dynamic1.C

Running the compiled version results in errors like
Error in : Error evaluating expression (DynamicExec()).
Execution of your code was aborted.
input_line_35:2:3: error: use of undeclared identifier ‘DynamicExec’
(DynamicExec())

Whereas loading it in ROOT and doing a Dynamic() works fine.
So my basic question is whether or not there is a way to pass the address of DynamicExec in the compiled code or not.
Dynamic1.C (3.0 KB)

Hi Peter,

When you compile code, I recommend to use following command:

g++ `root-config --cflags` `root-config --glibs` Dynamic1.C -o dynamic   

And one needs some workaround to invoke compiled function from interpreter - used by TExec.
Something like plain function pointer:

TString sexec = TString::Format("typedef void (*FunctionFunc)(); FunctionFunc foo = (FunctionFunc) 0x%x; foo();", &DynamicExec);

Working example:
Dynamic1.C (3.1 KB)

In principle, one could add function to the dictionary and then use it without such workaround.
Therefore if you generates dictionary in your project, add following line to linkdef.h:

#pragma link C++ function DynamicExec;

Regards,
Sergey

Thanks Sergey & Monica ! The function pointer method works like a charm !

One more question : Can I pass an argument string to the function as well ? Like if I want to call for example DynamicExec ( TH1F*, Int_t, Int_t ) ?

Similar functionality is implemented “direct” in TH1/2 and TGraph classes = Highlight mode for histogram and graph:

or try tutorials:

  • tutorials/graphs/hlGraph*.C
  • tutorials/hist/hlHisto*.C

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.