[sv-cc] C Macros For C++ Virtual Function access

From: Kevin Cameron <kcameron@altera.com>
Date: Wed Oct 06 2004 - 17:45:24 PDT

The attached file demonstrates C macros for accessing C++ virtual
functions for the Sunpro C++ compiler on Solaris, it's basically the
same as the GNU version except there appears to be a 2-slot offset
before the user functions. The file also compiles and runs with g++ on
Solaris and Linux. If most compilers generate vtables which are similar
except for an offset, you can export the offset from the simulator to
make code binary compatible (if you want to be able to use the same C++
compiler as well as C), similarly if the simulator knows which C++
compiler the user code was built with it could serve the appropriate
type of vtables (attributes on the function import declarations could be
used if you want to do it per-call when libraries are from different
compilers).

Virtual functions solve most of the problems of binary incompatibility
between vendors internal data representations, aren't particularly hard
to implement
and are probably more efficient than creating normalized copies of data
to pass to DPI user functions. Using them from C is not hard, and
compatibility with most C++ compilers is not difficult to achieve (as a
longer term goal).

Kev.

-- 
Altera Corp, 101 Innovation Drv, San Jose, CA 95134. T# (408) 544 7126

#include <stdio.h>

#ifdef __SUNPRO_CC
int offset = 2;
#else
int offset = 0;
#endif

class test {
public:
  virtual int fn_a(); // creates vtable pointer as first field in class
  virtual int fn_b();
};

int test::fn_a() {return 23;}
int test::fn_b() {return 42;}

class test2 :test { // derived class with different implementation of fn_a/b
  virtual int fn_a();
  virtual int fn_b();
  int n;
public:
  test2() {n = -42;}
};

int test2::fn_a() {return -23;}
int test2::fn_b() {return n;}

// C Macros
typedef int (*IFN)(...);
#define FN_A(h) (*((IFN *)*(void **)h)[offset+0])(h)
#define FN_B(h) (*((IFN *)*(void **)h)[offset+1])(h)

void DPI(void *h)
{
  printf ("%d\n",FN_A(h));
  printf ("%d\n",FN_B(h));
}

  
int main(int argc,char **argv)
{
  DPI(new test);
  DPI(new test2);
}
Received on Wed Oct 6 17:45:33 2004

This archive was generated by hypermail 2.1.8 : Wed Oct 06 2004 - 17:45:46 PDT