Hello Rooters,
I come back from my trip and ready to answer some of your questions.
It seemed like there were 2 questions regarding interpreted and compiled
code relationship.
1) How to call interpreted function from compiled code
2) Can interpreted class inherit from compiled class
The classic answer to this is quoted by Rene already. I'd like to
offer old but not advatised cint functionality , that is "STUB"
dictionary generation. With this, you can do both 1) and 2)
in some sense. I will explain this using an example.
# t350.dll STUB class/function definition
STUB class/function is a partly compiled class/function. Basically, you
compile only interface of specific class or function and let interpreter
interpret definition of member function or global function.
There are 4 files in this example.
t350.h : header for precompiled class/function
t350.cxx : source for precompiled class/function
t350s.h : header for STUB class/function interface
t350s.cxx: interpreted source file
There are 2 classes,
class a; // precompiled class
class b : public a; // interface only is compiled, member functions are
// interpreted
Class a and b have virtual function f(). a::f() and b::f() are resolved
by compiler's VTBL mechanism. Cint generates dummy for b::f() which calls
interpreted b::f(). If you are curious, pllease look into generated
dictionary G__cpp_t350.cxx.
There are 4 global functions,
main() : interpreted main function (t350s.cxx)
test() : precompiled function (t350.cxx)
g() : interface is precompiled and definition is interpreted.
Cint generates dummy g() which calls interpreted g(). If you
are curious, please look into generated dictionary.
scanall() : precompiled function (t350.cxx)
Remarkable things here are
1) interpreted funciton g() is directly used in copiled code test()
2) virtual function resolution is done in mixed interpreted/compiled
code environment in scanall().
This functionality has been implemented several years ago. There is a
bug in cint and you can not use it with current version. So you can not
run it with cint5.14.32 or older. I will fix the bug in cint5.14.33.
Thank you
Masaharu Goto
----------------------------------------------------------------------
makecint/cint command
$ makecint -mk maket350 -dl t350.dll -H t350.h -i++ t350s.h -C++ t350.cxx
$ make -f maket350
$ cint t350s.cxx
a::f()
b::f()
b::f()
a::f()
----------------------------------------------------------------------
// t350.h , precompiled class header file
#ifndef T350_H
#define T350_H
#include <stdio.h>
class a {
public:
int x;
virtual void f() {printf("a::f()\n");}
};
void scanall(a** obj,int n) ;
void test() ;
#endif
----------------------------------------------------------------------
// t350.cxx , precompiled class/function definition
#include "t350.h"
extern void g();
void scanall(a** obj,int n) { // compiled
for(int i=0;i<n;i++) {
// precompiled a::f() or interpreted b::f() will be called
obj[i]->f();
}
}
void test() { // compiled
g(); // interpreted function g() called from compiled code
}
----------------------------------------------------------------------
// t350s.h , stub definition for partly compiled and partly interpreted class
#ifndef T350S_H
#define T350S_H
#include "t350.h"
class b : public a { // class b definition precompiled
public:
int y;
void f(); // body of b::f() is interpreted
};
void g(); // g() is interpreted
#endif
----------------------------------------------------------------------
// t350s.cxx , interpreted source
#include "t350.dll"
void g() { // stub of g() is precompiled, but body is interpreted
a* obj[4];
obj[0] = new a;
obj[1] = new b;
obj[2] = new b;
obj[3] = new a;
scanall(obj,4);
}
void b::f() { // class b interface is precompiled, but b::f() is interpreted
printf("b::f()\n");
}
main() {
test();
}
// Operation of this program
//
// main() -> test() -> g() -> scanall() -> a::f()
// interpreted compiled interpreted compiled virtual-intp/com
// t350s.cxx t350.cxx t350s.cxx t350.cxx t350.cxx/t350s.cxx
----------------------------------------------------------------------
>
>Anton,
>You can read the following extract from the CINT FAQ at:
> http://root.cern.ch/root/Cint.phtml?faq
>I understand from Masa that inheriting from a compiled class
>could be implemented in the medium long term. This is highly
>machine/compiler
>dependent.
>Note that this limitation can be removed if you use the script compiler.
>I posted an example last week.
>
>Rene Brun
>
>
>############################################################################
># Can I inherit precompiled class from an interpreted class?
># Virtual function sometimes does not work properly.
>
> Cint supports class inheritance and virtual function calls in almost
>full
> C++ spec both within interpreted classes and precompiled classes. But
> there is fundamental difficulty in mixing interpreted/precompiled
>virtual
> functions.
>
> You could inherit precompiled class from an interpreted class, however,
> virtual function calls do not work properly. Every C++ compiler has
> proprietary Virtual Function Table format which is heavily
>implementation
> dependent. It is impossible for cint to match VTBL format of every C++
> compiler. Cint has its'own virtual function resolution mechanism. So,
> virtual function or virtual base class can only be resolved within
> interpreted classes or precompiled classes.
>
> There exist other C++ interpreter which allows virtual function
>resolution
> accross the interpreted/precompiled class boundary. But they severly
> sacrifice portability among different OS and compiler. Cint does not do
> this because portability is the primary importance to its concept.
>
> There is another case that virtual function of a precompiled class
> does not work properly. If you call virtual function of a precompiled
> class with scope operator, polymorphic resolution should be disabled
> and given specific function should be called. However in cint, you
> can not disable polymorphic resolution of a precompiled virtual
>function.
> This leads to calling wrong function if base and derived classes are
> both precompiled.
>
>Anton Fokin wrote:
>>
>> Hi,
>>
>> Another stupid question. CINT macro classes can not be inherited from
>> compiled classes. That's pity but true because of the different virt tables
.
>> (By the way, is there any thoughts that this will every be possible?) Is
>> there a way to substitute (overload) a function from compiled code in CINT
>> macro? Or the only way to work with a user defined function is via
>> SetFCN(void (*fcn)) as it is done in TMinuit?
>>
>> Best,
>> Anton
This archive was generated by hypermail 2b29 : Tue Jan 02 2001 - 11:50:21 MET