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

rh@jupiter.UUCP (#Rachid Himmi) (06/26/91)

I'm looking for the way to call a C++ module from a C program through
the declaration of a class and the call of its function members.

Does someone have some informations or some experience about this probleme.

Thanks in advance.

R. HIMMI

ark@alice.att.com (Andrew Koenig) (06/27/91)

In article <359@soleil.jupiter.UUCP> rh@jupiter.UUCP (#Rachid Himmi) writes:

> I'm looking for the way to call a C++ module from a C program through
> the declaration of a class and the call of its function members.

Turn your C program into a C++ program and it's easy.
Otherwise, it's a matter between you and your implementer(s)
and it's not guaranteed to work no matter what you do.
-- 
				--Andrew Koenig
				  ark@europa.att.com

alanb@sdl.mdcbbs.com (06/28/91)

In article <20463@alice.att.com>, ark@alice.att.com (Andrew Koenig) writes:
> In article <359@soleil.jupiter.UUCP> rh@jupiter.UUCP (#Rachid Himmi) writes:
> 
>> I'm looking for the way to call a C++ module from a C program through
>> the declaration of a class and the call of its function members.
> 
> Turn your C program into a C++ program and it's easy.
> Otherwise, it's a matter between you and your implementer(s)
> and it's not guaranteed to work no matter what you do.
> -- 
> 				--Andrew Koenig
> 				  ark@europa.att.com

In version 1, functions not declared as overloaded generally got the same name
as C functions would. In version 2, the linkage specification extern "C" can be
used to ensure this (Annotated C++ Reference Manual, Ellis and Stroustrup,
section 7.4)

e.g.

class class1
{
  public:
    void foo();
};

// C++ definition
extern "C" void CLASS1_foo( struct class1_t *me ) { me->foo(); }

/* C header file */
extern void CLASS1_foo( struct class1_t *me );

Season with friend declarations if you need a C interface to private functions,
and cast/constructor operators to turn your classes into C types.

(If you use structs in C++, they will be the same in C, but normally I would
expect the module to be passing out an opaque type. "(void *)this" will often
do, but having a type that reflects the C++ type is cleaner.)

alanb@sdl.mdcbbs.com    Alan Braggins    #include <disclaimer.hxx>

dab@ubitrex.mb.ca (Danny Boulet) (06/28/91)

In article <20463@alice.att.com> ark@alice.UUCP () writes:
>In article <359@soleil.jupiter.UUCP> rh@jupiter.UUCP (#Rachid Himmi) writes:
>
>> I'm looking for the way to call a C++ module from a C program through
>> the declaration of a class and the call of its function members.

In your C++ code, write C callable functions that invoke the C++ members.
For example:

---------------------- C++ code ------------------------

class fred {

public:
	.
	.
	.
    int doit(int x);
	.
	.
	.
};

extern "C" int
freddoit(void *ptr,int x)
{
    fred *p = (fred *)ptr;
    return( p->doit(x) );
}

----------------------------------------------------------

Call "freddoit" from C with a pointer to an instance of "fred" as the first
parameter and (in this example) an appropriate value for "x" as the
second parameter:

---------------------- C code ----------------------------

    w = freddoit(fredptr,124);

----------------------------------------------------------

I've no idea if this is supposed to work but it does for me.

>
>Turn your C program into a C++ program and it's easy.
>Otherwise, it's a matter between you and your implementer(s)
>and it's not guaranteed to work no matter what you do.
>-- 
>				--Andrew Koenig
>				  ark@europa.att.com

hargrove@asc.slb.com (Jim Hargrove) (06/29/91)

>>>>> dab@ubitrex.mb.ca (Danny Boulet) writes:
The listing below shows one way of calling a C++ function from a C
program. There is one slight enhancement that we can make. Instead of
propagating yet another void *, we can define a C typedef to use in
pointing to a C++ object. In the case below, where the class is named
fred, we define

    typdef  struct  fred    *   CFred_t;

As the struct fred is not defined in the C scope this is an
"incomplete" type definition in ANSI C. Only pointers can be defined
in this way.

Then the definition of the function freddoit becomes

    int
    freddoit(CFred_t    myFred,
             int        x);

This means that the compiler can distinguish between pointers to freds
and pointers to other objects. 

We should avoid void * whenever possible.

dab> In article <20463@alice.att.com> ark@alice.UUCP () writes:
>In article <359@soleil.jupiter.UUCP> rh@jupiter.UUCP (#Rachid Himmi) writes:
>
>> I'm looking for the way to call a C++ module from a C program through
>> the declaration of a class and the call of its function members.

dab> In your C++ code, write C callable functions that invoke the C++ members.
dab> For example:

dab> ---------------------- C++ code ------------------------

dab> class fred {

dab> public:
dab> 	.
dab> 	.
dab> 	.
dab>     int doit(int x);
dab> 	.
dab> 	.
dab> 	.
dab> };

dab> extern "C" int
dab> freddoit(void *ptr,int x)
dab> {
dab>     fred *p = (fred *)ptr;
dab>     return( p->doit(x) );
dab> }

dab> ----------------------------------------------------------

dab> Call "freddoit" from C with a pointer to an instance of "fred" as the first
dab> parameter and (in this example) an appropriate value for "x" as the
dab> second parameter:

dab> ---------------------- C code ----------------------------

dab>     w = freddoit(fredptr,124);

dab> ----------------------------------------------------------

dab> I've no idea if this is supposed to work but it does for me.

>
>Turn your C program into a C++ program and it's easy.
>Otherwise, it's a matter between you and your implementer(s)
>and it's not guaranteed to work no matter what you do.
>-- 
>				--Andrew Koenig
>				  ark@europa.att.com
-- 

        -- jwh