[comp.lang.c++] calling C++ from C,Scheme,Lisp and other languages

ham@Neon.Stanford.EDU (Peter R. Ham) (06/10/90)

I'm writing a large application in C++. It includes Scheme as
the extension language, so Scheme needs to be able to call C++.
This problem is not really Scheme specific. Calling C++ from
other languages like C and Lisp should present similar problems.

Let's say that I write a C function called, "call_c++()", the arguments
of the function are:
1) the (un qualified ) name of the C++ member function, assume in
character string form for now
2) a pointer to the object that the member function will be invoked on
3) a variable length list of pointers to the C++ objects that are the arguments
that the member function will be invoked withto the arguments that 

The operations that "call_c++" needs to perform are:
1) map the function name and the class of the "receiving" object to 
the address of the member function to be called
2) adjust the "this" pointer of the "receiving object" to match the structure
layout expected by the member function
3) adjust the "this" pointers of the argument objects to match the structure
layouts expected by the member function

The problem:
The function "call_c++" needs access to type (or class) information about
objects at run time.  (I realize that Mark Linton wrote a paper on this, 
but I haven't got a copy yet. ) 

Some of this type information is available in an object's virtual function
table. I'm still pretty confuse about how virtual function tables are
layed out, especially with multiple inheritance. Can anyone suggest a
reference on this? Is this area too compiler specific to design a scheme
that works across C++ implementations?

Can anyone think of a clever way to coax the C++ compiler to spit out
the information I need other than virtual function tables? I think I need
more information than the vtable will provide.

Specifically, is there a way to determine an objects class at run time.
As I understand it, inside a C++ object is contained a pointer to its
virtual function table, no? Is this effectively it's type? It seems that
there should be only one vtable per class, but these might be duplicated
due to the C++ compilation and linking process, no? Is there a way
to ensure that only one vtable per class is produced? This might be considered
a linking problem, but I want to have some kind of class identifier and
multiple (but identical) vtables would foil this scheme.

One idea I have is to hack g++'s front end in order to generate portions
of my "call_c++" function automatically. I'm not sure how hard this would
be, but might go a long way towards automating this inter-language function
calling mechanism. I could get the front end to print out 
1) a description of the c++ class hiearchy
2) the sizes of class structures
3) a mapping from classes and member function names to the member function 
addresses
4) descriptions of the types of the arguments of member functions
5) descriptions of how to cast one C++ class object to a super class or
sub class object

I'd appreciate any references or suggestions.
--
Peter Ham			PO Box 3430	(h)(415) 322-4390
MS Computer Science Student	Stanford, CA	ham@cs.stanford.edu
Stanford University 		94309		(o)(415) 723-2067

roman@ektools.UUCP (Bill Romanowich) (06/13/90)

I would like to hear comments about whether/how C++ applications can be 
called by 3GL applications in general. 
 
This is a topic that I don't remember seeing discussed anywhere (please
correct me if I'm wrong).  The situation I am talking about is
integrating an application written in C++ into an environment where
there are already some other software packages running.  The expectation
would be that the C++ application would be able to integrate with the
other software packages and processes (C++ --> others, others --> C++), 
perhaps through some sort of APIs (Application Programming Interfaces) 
and interprocess communications methods.
 
Aren't there some real differences in "interface" issues between C++ and
non-object oriented languages?  
 
Please forgive me if this is a dead horse, but I don't remember seeing
it discussed before.  Discussions of C++ that I have seen appear to assume
that the C++ applications are basically "alone" and do not have to
communicate/connect with other "stuff". 
 
 
A (perhaps) related topic: What if this mythical C++ application is not
all C++, but has higher-level layers written in C++ and lower level
layers written in non-object oriented language(s), perhaps including but
not restricted to C.  Not a problem? 
 
In my experience, discussions of C++ seem to assume that the whole
application is written in the language, and don't really deal with the
concept of layers of functionality being implemented in different
languages. 
 
 
If people wish to reply via mail instead of to the net, I am willing to
summarize.  Two possible mail paths to me:
 
  gaffaney@imagemaker.Kodak.COM
               *or*
  imagemaker!gaffaney@Kodakr.Kodak.COM
 
Thanks,
Dan Gaffaney
-- 
Bill Romanowich 		(ektools!roman@kodakr.kodak.com)  
UUCP   : {allegra,rutgers}!rochester!kodak!ektools!roman
USMail : System Solutions Group, Eastman Kodak Co., Rochester, NY 14653-5819
Phone  : (716) 726 - 0217	SSG User Interface Software

fkittred@bbn.com (Fletcher Kittredge) (06/13/90)

In article <2701@ektools.UUCP> gaffaney@imagemaker.Kodak.COM (Dan Gaffaney) writes:
>I would like to hear comments about whether/how C++ applications can be 
>called by 3GL applications in general. 
> 
>This is a topic that I don't remember seeing discussed anywhere (please
>correct me if I'm wrong).  The situation I am talking about is

Well, I can't tell you if you have seen it discussed anywhere, because
I don't know what you have read ;-), but it is perfectly straightforward
and easy to use.  Perhaps this is why it hasn't had much discussion.

The most widely used language to call C++ from is C.  Lippman pp 174-176
discusses how this is done.  The mechanism is called an 'extern string
directive' and is supposed to work with a wide variety of languages.  I
have only have occasion to use it with C.  Lippman also has useful
appendicies on the linkage between C and C++ and how to transition
applications and programmers between C and C++.

From my perspective, the ability to intermix C and C++ is one of the major
strengths of C++.  If you use C in a Unix environment, you have probably
already used this feature without knowing it.


>Thanks,
>Dan Gaffaney
>-- 

no problem,
fletcher


Fletcher E. Kittredge  fkittred@bbn.com
Platforms and Tools Group
BBN Software Products Company
10 Fawcett St.
Cambridge, MA. 02138

davidm@uunet.UU.NET (David S. Masterson) (06/14/90)

In article <2701@ektools.UUCP> roman@ektools.UUCP (Bill Romanowich) writes:

   I would like to hear comments about whether/how C++ applications can be 
   called by 3GL applications in general. 

Is this what the 'extern "C" {' construct is for?  Placing function
declarations within this construct will inform C++ that these functions were
defined without the C++ function name "swizzling" and, therefore, are called
as is.  Therefore, C++ can call functions written in other languages when they
are identified with this construct.

On the flip side, is it true that functions that are not methods or friends of
any object are not "swizzled" and, therefore, usable by other languages?
--
===================================================================
David Masterson					Consilium, Inc.
uunet!cimshop!davidm				Mt. View, CA  94043
===================================================================
"If someone thinks they know what I said, then I didn't say it!"

pkturner@cup.portal.com (Prescott K Turner) (06/14/90)

ham@Neon.Stanford.EDU (Peter R. Ham) writes:
> I'm writing a large application in C++. It includes Scheme as
> the extension language, so Scheme needs to be able to call C++.
...
> 3) a variable length list of pointers to the C++ objects that are the 
>    arguments
Calling C++ from Scheme would involve plenty of problems if all you needed
was to call an arbitrary conventional (non-member) function.  Presumably
you're up to the chore of taking a variable length list of pointers and
invoking an arbitrary, prototyped function, passing as arguments the objects
pointed to.

The representation of objects and member functions is very much up to the
C++ implementation.  So the lines along which you are thinking won't
yield a portable solution, even if C++ implementations did keep around the
types of all objects at run-time.

Consider creating a base class, "callable", with a virtual function that
can be called to do the work of dispatching to the desired member function.
    class callable {
        virtual void dispatch (const char * func_name, char * args);
        };
    extern "C" void call_c_plus_plus (callable * obj, 
                                      const char * func_name,   
                                      char * args) {
        obj->dispatch (func_name, args);
        }
Every class which is to be callable from Scheme would be derived from
"callable", and would have its own dispatch function written.  (I've
made args simple, since that's not a problem unique to C++.
--
Prescott K. Turner, Jr.
Language Processors, Inc.
959 Concord St., Framingham, MA 01701 USA    (508) 626-0006 x232
UUCP: ...sun!cup.portal.com!pkturner    Internet: pkturner@cup.portal.com

    

jimad@microsoft.UUCP (Jim ADCOCK) (06/15/90)

In article <57378@bbn.BBN.COM> fkittred@spca.bbn.com (Fletcher Kittredge) writes:
|The most widely used language to call C++ from is C.  Lippman pp 174-176
|discusses how this is done.  The mechanism is called an 'extern string
|directive' and is supposed to work with a wide variety of languages.  I
|have only have occasion to use it with C.  Lippman also has useful
|appendicies on the linkage between C and C++ and how to transition
|applications and programmers between C and C++.
|
|From my perspective, the ability to intermix C and C++ is one of the major
|strengths of C++.  If you use C in a Unix environment, you have probably
|already used this feature without knowing it.

This all works great as long as the C and the C++ code is linked together
with a C++ linker that understands the fixups necessary to get C++ 
static initializers called at runtime.  However, requiring a C++ linker seems
like an unrealistic restriction when making libraries compatible with C.
How have people addressed this issue?  Just avoided static objects in classes
designed for C compatibility?