Re: Callable inerpreter

From: Rene Brun (Rene.Brun@cern.ch)
Date: Tue Jul 27 1999 - 22:38:32 MEST


Hi Andy,

Let's have a small example with the following files:
//------------------------------ A.h
#ifndef __A_HH__
#define __A_HH__
///#include "TObject.h"

class A {
public:

  A();
  virtual ~A();
  
  int fA;
  int fB;
  
///  ClassDef(A,1)
};

#endif

//------------------------------ A.cxx
#include "A.h"

// ClassImp(A)

A::A() {
  fA = 1;
  fB = 2;
}

A::~A() {
}

//------------------------------ ALinkDef.h

#ifdef __CINT__

#pragma link off all globals;
#pragma link off all classes;
#pragma link off all functions;

#pragma link C++ class A;
#endif

//------------------------------ test2.cxx
class A;
  class B {
    public:
      B() {}
      void doSomething(const A *a);
  };

void B::doSomething(const A *a)
{
   printf("fA=%d, fB=%d\n",a.fA, a.fB);
}

void test1() 
{
   A *a = new A;
   B *b = new B;
   b->doSomething(a);
}  
void test2()
{
   gInterpreter->ProcessLine("{A *a = new A; B *b = new B;
b->doSomething(a);}");
}


Now (eg on Linux) execute the following shell script commands:
rootcint -f Acint.cxx -c A.h ALinkDef.h
g++ -fPIC -I$ROOTSYS/include -c Acint.cxx A.cxx
g++ -g -Wl,-soname,A.so -shared Acint.o A.o -o A.so

The above 3 commands run the rootcint processor to create the dictionary
for class A, compile and create a shared lib "A.so" with all the necessary
A files.

Now run the following interactive Root session:

Root > gSystem->Load("A");  
Root > .L test2.cxx
Root > test1();
Root > test2();

Instead of the above Root session, you could create a small macro
//-------------------macro andy.C
{
   gSystem->Load("A");  
   gROOT->LoadMacro("test2.cxx");
   test1();
   test2();
}

and run the following Root interactive session
Root > .x andy.C

Rene Brun




On Tue, 27 Jul 1999, Andy Salnikov wrote:

>   Hi ROOTers,
> 
>   I'm trying to use ROOT as a "callable" interpreter. Say, I have an
> object in the compiled program on which I want to run an interpreted
> code. Let's say I have following code:
> 
>   // --- test1.h - will be processed with |rootcint|
> 
>   class A {
>     public:
>       A(int) {}
>       // ....
>     private:
>       // ....
>   };
> 
>   // --- test2.cxx - this the interpreted code
> 
>   class B {
>     public:
>       B() {}
>       doSomething(const A*) {}
>   };
> 
> Now what I want is to create an object of class A in the compiled code
> and pass it to the B::doSomething(). I have something like this in the
> main():
> 
> 
>    TApplication *theApp = new TRint(appname, &argc, argv, 0, 0);
> 
>    theApp->ProcessLine(".L test2.cxx");    // load interpreted code
>    theApp->ProcessLine("B *b = new B;");   // create an instance of
> class B in interpreter
> 
>    A *a = new A ;                          // make an instance of "A" in
> compiled program
> 
>    // Now how do I?
>    theApp->ProcessLine("b->doSomething(a);"); // "a" means above
> allocated a
> 
> All I could think of is to take an address of "a" and make a cast,
> something like that:
> 
>   char buf[64] ;
>   sprintf ( buf, "b->doSomething((A*)%d);", &a ) ;
>   theApp->ProcessLine( buf ) ;
> 
> That looks quite clumsy, and I'm not at all sure this will work. So,
> does someone have a nice solution for this? Probably I should play with
> the dictionary to make "a" seen to the interpreter? But how do I do
> this?
> 
>   Cheers,
>   Andy.
> 
> 



This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:43:36 MET