[DotGNU]Strategy for dealing with C++ virtual functions in a managed binding.

James Michael DuPont mdupont777 at yahoo.com
Tue Dec 3 06:24:32 GMT 2002

--- Adam Treat <manyoso at yahoo.com> wrote:
> On Tuesday 03 December 2002 12:09 am, James Michael DuPont wrote:
> > --- Adam Treat <manyoso at yahoo.com> wrote:
> > > Hello All,
> > >
> > > I would like to pick the brains of the collective intelligence
> and
> > > come up
> > > with a good solid strategy for dealing with C++ virtual functions
> in
> > > a
> > > binding.
> >
> > /me ears pick up something interesting
> >
> > > Our new strategy is then to call the libqt.so directly using
> mangled
> > > method
> > > names in our DllImport attributes.
> > >
> > > This is accomplished by using a
> > > combination of 'nm' and 'cppfilt' during Qt# binding creation.
> >
> > I would like too see this code. /me thinks you can use libiberty
> and
> > the   introspector or gcc_xml for this.
> Oh, we already have a strategy for mangling the names.  A script and 
> nm+cppfilt works nicely.  I can produce this script for you tomorrow
> (it's 
> late ;)  We looked at libiberty for this, but it only provides a
> mechanism 
> for 'demangling' and does not provide a way to 'mangle' given a
> string 
> representing a function prototype.

Here is the code for getting it from the dbxout.c
you will notice that this information is stored in the tree structre.
	  /* This is the "mangled" name of the method.
	     It encodes the argument types.  */
	  const char *debug_name;

	  /* Skip methods that aren't FUNCTION_DECLs.  (In C++, these
	     include TEMPLATE_DECLs.)  The debugger doesn't know what
	     to do with such entities anyhow.  */
	  if (TREE_CODE (fndecl) != FUNCTION_DECL)


> > >  The
> > > idea is
> > > to use an instance pointer as an invisible first parameter and
> then,
> > > using
> > > the mangled name, call libqt directly.
> >
> > like the gnu libjava
> Oh?  libjava uses this method?  Is this part of gcj then?
Look at libjava/java/net/natPlainSocketImpl.cc
java::net::PlainSocketImpl::bind (java::net::InetAddress *host, jint

this is a clean an interface as you will get.

> > >  Oh, and our binding generator
> > > is also
> > > capable of an easy extension to bind any C++ lib in case anyone
> is
> > > interested
> > > in binding other C++ libraries ;)
> >
> > yes, let us see the basic axioms, we can build this in a standard
> > process.
> >
> > at this point, I would like to know why cannot you use the internal
> > call system? that has a binding generator as well, no?
> The binding generator is pretty flexible and easy to extend to other
> C++ 
> API's.  

> We use a custom C++ header parser written in C# to produce an
> XML 
> file representing the C++ API.  
do you have a spec of the output, I could output this directly from the

> This XML file is then processed
> through our 
> binding generator called 'binge'. 

> What do you mean by 'use the
> internal call 
> system' ?? 
see cvs/pnetlib/doc/native
<title>Internalcall methods for pnetlib</title>
cvs/pnet/engine/int_table.c, here is a lookup table of method pointers
(in c) that could be translated somehow into c++.
I still have lots to read. But it looks promising.
#ifndef _IL_Decimal_suppressed
	IL_METHOD("Round", "(vSystem.Decimal;i)vSystem.Decimal;",
_IL_Decimal_Round, marshal_vpppi)
	IL_METHOD("Compare", "(vSystem.Decimal;vSystem.Decimal;)i",
_IL_Decimal_Compare, marshal_ippp)
	IL_METHOD("Truncate", "(vSystem.Decimal;)vSystem.Decimal;",
_IL_Decimal_Truncate, marshal_vppp)

> I have no idea what you are referring to nor do I
> understand 'has 
> a binding generator as well, no' ... what has a binding generator as
> well?
Sorry for the ambigiguity. I mean the pnet internal calls.
Well there are many files in the pnet that have a scary 
notice "dont touch, autogenerated"
unfortually there is no statement about what program generated them.
I will have to look into this.

> > >  The preferred solution would
> > > be to
> > > somehow override the virtual table to call a managed function
> > > directly and
> > > then somehow forward this to the appropriate C# virtual function.
> >
> > you can grab pointers to virtual function entries,
> > and given an object and a vf pointer call the object.
> >
> > please send me more info,
> > I just might be able to help.
> Awesome!  I don't know what kind of info would be helpful

1. the spec for the xml description of the bindings
2. a single c+ header file with the class definitions that you want to

> ... Our
> ideal 
> solution would allow us to associate a delegate with a C# virtual
> function 
you mean c++ virtual function.

> ... when the virtual function is implemented the binding would pass
> the delegate to a C glue method as a function pointer ... 

> the C glue method could 
> then do some magic with the virtual table in libqt.so and install the
> delegate in place of the existing function pointer. 
You want to overwrite the c++ vtable so that you can call C# from c++,
via the method table?

ok, this will require setting the function pointer of an existing
method. Or involve a second interface.

I would say that i need an exact example,
assuming you could modify the make_thunk function from the gcc,
then you call the c# code.
the makethunk is used on the client side
    fn = make_thunk (fn, delta, vcall_index);
this is called in the function cp/class.c/build_vtbl_initializer
int the gcc. There you could set the function pointers.


>  I know how to do
> all of 
> this except play with the Qt vtable in native code ...

Well, please send me an example of that. 


James Michael DuPont

Do you Yahoo!?
Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
>> Visit http://mail.kde.org/mailman/listinfo/kde-devel#unsub to unsubscribe <<

More information about the kde-core-devel mailing list