[comp.lang.c++] calling C++ from C

pts@faraday.clas.Virginia.EDU (Paul T. Shannon) (04/15/91)

Though many books explain how to call C functions from C++, I'm 
having difficulty figuring out how to do the opposite.  

I have a large C program, built from several modules of Ansi C 
code.  I want to add two C++ modules to this, and call the member 
functions from the C program.

Do I have to determine how my compiler (Turbo C++ version 1.01) 
mangles names, and then call the member functions with those
names?

Thanks for any help.

 - Paul Shannon
   pts@Virginia.EDU

steve@taumet.com (Stephen Clamage) (04/16/91)

pts@faraday.clas.Virginia.EDU (Paul T. Shannon) writes:

>Though many books explain how to call C functions from C++, I'm 
>having difficulty figuring out how to do the opposite.  

>I have a large C program, built from several modules of Ansi C 
>code.  I want to add two C++ modules to this, and call the member 
>functions from the C program.

It is interesting that this question comes up three times in today's
news.  The answer is that the same mechanism serves both requirements.
You may declare and define a C++ function as
	extern "C" ...
and call it from a C program, as long as
1.  The function is not a member of any class.
2.  No more than one overloaded version of the function is so declared.
3.  The function declaration requires only types visible to the C program.

Requirement 3 can be relaxed a bit by using pointers to C++ class types,
if no object of the type is needed by the C program.  That is, a C++
function can pass a pointer to a class object to a C function, which can
pass on that pointer to another C++ function.  In the C file, you
just use the incomplete declaration
	struct SomeClass;
and then use pointers to struct SomeClass.  You cannot safely provide
"equivalent" C declarations of C++ classes, since you cannot portably
predict how the C++ compiler will lay out the class members.

You can relax Requirements 1 and 2 by providing "wrapper functions" in
C++.  Example:

C++ file:
=========
	class SomeClass { ... int f1(int); ... };
	extern "C" int call_f1(SomeClass* p, int i) // wrapper for C
	{
	    return p->f1(i);
	}

C file:
========
	struct SomeClass;			/* defined in C++ files */
	int call_f1(struct SomeClass*, int);	/* defined in C++ files */

	int myfunc(struct SomeClass* p)
	{
	    ... call_f1(p, 3) ...
	}
-- 

Steve Clamage, TauMetric Corp, steve@taumet.com

masa@hpsciz.sc.hp.com (Masayoshi Habu) (04/17/91)

In comp.lang.c++, pts@faraday.clas.Virginia.EDU (Paul T. Shannon) writes:

    Though many books explain how to call C functions from C++, I'm 
    having difficulty figuring out how to do the opposite.  

    I have a large C program, built from several modules of Ansi C 
    code.  I want to add two C++ modules to this, and call the member 
    functions from the C program.

    Do I have to determine how my compiler (Turbo C++ version 1.01) 
    mangles names, and then call the member functions with those
    names?

    Thanks for any help.

     - Paul Shannon
       pts@Virginia.EDU

masa@hpsciz.sc.hp.com (Masayoshi Habu) (04/17/91)

In comp.lang.c++, masa@hpsciz.sc.hp.com (Masayoshi Habu) writes:

    In comp.lang.c++, pts@faraday.clas.Virginia.EDU (Paul T. Shannon) writes:

        Though many books explain how to call C functions from C++, I'm 
        having difficulty figuring out how to do the opposite.  

        I have a large C program, built from several modules of Ansi C 
        code.  I want to add two C++ modules to this, and call the member 
        functions from the C program.

        Do I have to determine how my compiler (Turbo C++ version 1.01) 
        mangles names, and then call the member functions with those
        names?


Sorry, I hit a wrong key while writing a response. Anyway, there is a
"correct" way to call a member function from C. You don't have to figure
out the function name. Let's have three global (non-member) functions
for this object. The first function creates an object and returns its
pointer to C. The second function receives the pointer and calls the
member function with the pointer. The third function also receives the
pointer and deletes it. All these function names need to be in the
famous 'extern "C" {}' construct. Note that this construct works also
for functions compiled by C++. It tells C++ compiler not to change the
functions names appear in the '{}'. Suppose I have a class A, then

extern "C" {
   A*   create_object();
   void call_member(A*);
   void delete_object(A*);
}

A* create_object() { return(new A()); }
void call_member1(A* target) { target->member_function1(); }
void delete_object(A* target) { delete target; }

If you want to call a member function directly, then you need to get
a pointer with the first function, then call the member function with
the pointer as its first argument. Of course, you can 'cheat' to know
the changed name of the member function by either looking at its C code
(when your C++ compiler emits C) or searching a plausible name in your
object file. But this is a non-standard way.

masa

landauer@morocco.Eng.Sun.COM (@morocco.eng [Doug Landauer]) (04/19/91)

> If you want to call a member function directly, then you need to get
> a pointer with the first function, then call the member function with
> the pointer as its first argument.

Note that this method is not portable.  C++ implementations exist
which pass "this" as the last parameter instead of the first.

> But this is a non-standard way.

So is the above suggestion.
-- 
Doug Landauer - Sun Microsystems, Inc. - Languages - landauer@eng.sun.com
    Matt Groening on C++:  "Our language is one great salad."

ldg@drywit.ATT.COM (XGPB30000-GibbonsD(DRR6702)262) (04/20/91)

From article <1991Apr15.154120.13484@murdoch.acc.Virginia.EDU>, by pts@faraday.clas.Virginia.EDU (Paul T. Shannon):
> Though many books explain how to call C functions from C++, I'm 
> having difficulty figuring out how to do the opposite.  
> 
> I have a large C program, built from several modules of Ansi C 
> code.  I want to add two C++ modules to this, and call the member 
> functions from the C program.
> 
> Do I have to determine how my compiler (Turbo C++ version 1.01) 
> mangles names, and then call the member functions with those
> names?

C++ provides a mechanism for this. In your C++ program you provide
something like

extern "C"
void
CallableFromC()
{
	// your C++ code here
}

The above function has "C" linkage, which in implementation
terms means its name is not mangled.

Invoking member functions from C is a bit trickier - wrap 
each call in a function as above to avoid the mangling
issues. 
--
--------------------------------------------------------------------------------
-- Doug Gibbons			| ldg@druhi.ATT.COM or att!druhi!ldg
-- AT&T Bell Laboratories 
-- Denver CO