Topic: Calling C++ functions from C functions
Author: "John Calcote" <jcalcote@novell.com>
Date: 1997/10/18 Raw View
Ajay Nilaver wrote in message ...
>Hello,
>
>I am writing an application in ANSI C. I would like to know whether
>it is possible to call a C++ function from within a C program. If so,
>how can it be achieved and do all compilers support this functionality?
>
>Thanks in hope of an early response.
Ajay,
What you are asking must be qualified a bit, but I'll try to interpolate
a
bit.
First realize that a non-static C++ member function only exists within
the
context of an instantiated object. When a program exports a public
member
function to the linker, what shows up in the object module is a symbol
mapped to the entry point of a routine that expects a valid "this"
pointer
as the first parameter. This routine is thus, unusable without an
object.
The class name and the entry points for all of the public (and
protected)
member functions are public object module symbols, and are exported as
"mangled" or "decorated" names. These mangled names have class and type
information embedded in them so as to distinguish them from other,
similarly
named public exports from other classes, or from the same class with a
different signature (parameter list).
Tell your linker to generate a map file for you of a C++ program with
exported classes. You will see in the map file the mangled names of the
class and public member functions.
If you declare a member function static, on the other hand, then no
"this"
pointer is expected as the first parameter. It's easier to call such a
function from a C function, but there are still problems.
The biggest problem you have is trying to use the mangled name in a C
source
file. The mangling or decorating algorithm is defined by the ANSI
discussion
docs as being "implementation dependent" - which means that every
compiler
vendor has invented its own system for embedding signature information
in
the public symbol - usually this symbolic overhead contains characters
that
C compilers don't like very much, such as '?' or '!'.
The best way to accomplish what you want for static functions is to
write a
globally defined C++ wrapper function. Have it call the static member
you
are interested in and declare it in an externally visible header file as
follows:
extern "C" /* return value, eg., int */ MyAccessor(/* parameters */);
Now it will be exported by the linker with "C" linkage, which means its
name
will not be mangled by the compiler.
If you want to access a non-static member function, then what you are
really
saying is that your C++ program has instantiated a globally available
object, which has a member function you want to call from outside your
program. Again, write a similar wrapper function, declared with "C"
linkage,
and have it access your object through the member you are interested in,
like this:
int MyAccessor(void)
{
return globalObject.memberFunction();
}
John Calcote
Directory Services
Novell, Inc.
---
[ comp.std.c++ is moderated. To submit articles: try just posting with
]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu
]
[ FAQ:
http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy:
http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu
]
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
Author: Ajay Nilaver <ajay.nilaver@tek.COM>
Date: 1997/10/14 Raw View
Hello,
I am writing an application in ANSI C. I would like to know whether
it is possible to call a C++ function from within a C program. If so,
how can it be achieved and do all compilers support this functionality?
Thanks in hope of an early response.
Ajay Nilaver
Software Engineer
Tektronix Engineering Development (India) Pvt. Ltd.
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Edward Diener <eddielee@abraxis.com>
Date: 1997/10/15 Raw View
With the C++ compilers on Windows, you must compile your C source file
as a C++ file in order to call other C++ functions successfully. Each
compiler has a command line method to do this and most have a method
within their IDE to do this. If you compile your C source file as a C
file, any call that you make to a C++ function will compile correctly
if you have the proper declaration for your C++ function but will not
link because the C++ function will have name mangling applied, whereas
C knows nothing about name mangling. Needless to say compiling a C
source file that attempts to instantiate an object and call member
functions will fail at the compile stage since C knows nothing of these
C++ feartures.
Ajay Nilaver wrote:
> I am writing an application in ANSI C. I would like to know whether
> it is possible to call a C++ function from within a C program. If so,
> how can it be achieved and do all compilers support this functionality?
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
Author: "Paul D. DeRocco" <pderocco@ix.netcom.crud.com>
Date: 1997/10/15 Raw View
Ajay Nilaver wrote:
>
> I am writing an application in ANSI C. I would like to know whether
> it is possible to call a C++ function from within a C program. If so,
> how can it be achieved and do all compilers support this functionality?
Well, if it calls a C++ function, it will no longer be an ANSI C
program, will it?
It should be possible to do, however, as long as the C++
function is compiled with extern "C" to make it in effect a C
function. Since many C++ library functions are in fact C library
functions, C++ compilers must provide a way for C++ programs to
call C functions. If the C++ subroutine linkage were
incompatible with the C subroutine linkage, then they'd have to
provide special C++ versions of the C libraries. I doubt anybody
actually does this, since it's much simpler to make the C++
compiler use the same subroutine linkage as C code. As long as
that's the case, the reverse should be true, which is to say
that the C++ compiler should be able to produce a C-callable
function. It's certainly true of the x86 compilers I've used.
If you don't have access to the C++ source, and the functions
you want to call weren't compiled with extern "C", then your
only choice is to write a C++ thunk module that contains
forwarding functions that _are_ declared with extern "C". (Or
write an assembly language module that defines C-callable entry
points that simply jump to the C++ functions, if the subroutine
linkage conventions are the same.)
--
Ciao,
Paul
(Please remove the extra "crud" from the return address,
which has been altered to foil junk mail senders.)
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1997/10/15 Raw View
Ajay Nilaver wrote:
>
> Hello,
>
> I am writing an application in ANSI C. I would like to know whether
> it is possible to call a C++ function from within a C program. If so,
> how can it be achieved and do all compilers support this functionality?
>
> Thanks in hope of an early response.
Declare the functions you want to call as extern "C" in your C++
program. Of course, you can't use class types from C, but you have
to stick to C types. If you want to pass objects to your C code and
back, you can do it in different ways:
1. Pass void* pointers to your objects between C and C++ functions
(reference semantics)
2. Pass handles between C and C++ functions (this is what most OSs do
with their internal objects: You get file handles, socket handles,
window handles, ...) (reference semantics)
Example:
/* common.h: included both in C and C++ */
#ifndef COMMON_H_INC
#define COMMON_H_INC
#ifdef __cplusplus
extern "C"
{
#endif
typedef int hText; /* Handle of a text */
typedef int Result; /* result of operation (success/error)
*/
#define NO_TEXT 0 /* indicates failure of creating text */
#define RS_SUCCEEDED 0 /* no error */
#define RS_ERR_BAD_HANDLE 1 /* error: bad handle given */
#define RS_ERR_FAILED 2 /* error: operation failed */
hText NewText(void); /* Create new text */
void DeleteText(hText); /* DeleteText */
Result Append(hText, hText); /* Append second text to first */
...
#ifdef __cplusplus
}
#endif
#endif /* !COMMON_H_INC */
// cpponly.h: class definition for C++
#ifndef CPPONLY_H_INC
#define CPPONLY_H_INC
class Text
{
public:
Text();
~Text();
void Append(const Text&);
...
};
#endif
// C++ implementation for common.h header:
#include "common.h"
#include "cpponly.h"
class TextHandle
{
map<Text*, int> text2handle;
map<int, Text*> handle2text;
hText current_handle;
TextHandle(): current_handle(NO_TEXT) {}
TextHandle& myself()
{
static TextHandle me;
return me;
}
public:
static hText register(Text* text)
{
hText ht=++myself().current_handle;
myself().text2handle[text]=ht;
myself().handle2text[ht]=text;
return ht;
}
static Text* deregister(hText ht)
{
Text* text=myself().handle2text[ht];
myself().handle2text[ht]=(Text*)0;
myself().text2handle[text]=NO_TEXT;
return text;
}
static hText get_handle(Text* text)
{
return myself().text2handle[text];
}
static Text* get_text(hText ht)
{
return myself().handle2text[ht];
}
}
hText NewText() // extern "C" already at definition in common.h;
{ // no need to repeat it here
try
{
Text* text=new Text;
}
catch(...) // something went wrong
{
return NO_TEXT;
}
return TextHandle::register(text);
}
void DeleteText(hText ht)
{
delete TextHandle::deregister(ht);
}
Result AppendText(hText ht1, hText ht2);
{
Text* text1=TextHandle::get_text(ht1);
if(text1==(Text*)0)
return RS_ERR_BAD_HANDLE;
Text* text2=TextHandle::get_text(ht2);
if(text2==(Text*)0)
return RS_ERR_BAD_HANDLE;
try
{
text1->Append(*text2);
}
catch(...)
{
return RS_ERR_FAILED;
}
return RS_SUCCEEDED;
}
/* c file using Text objects: */
#include "common.h"
int main()
{
hText ht1, ht2;
ht1=NewText();
if(ht1==NO_TEXT)
return 1;
ht2=NewText();
if(ht2==NO_TEXT)
return 1;
if(AppendText(ht1, ht2)!=RS_SUCCEEDED)
return 1;
DeleteText(ht1);
DeleteText(ht2);
return 0;
}
3. Define a C struct which contains all necessary data, and add a
conversion function from/to this struct to the class (reference
semantics and value semantics; breaks encapsulation, of course)
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Edward Diener <eddielee@abraxis.com>
Date: 1997/10/15 Raw View
With the C++ compilers on Windows, you must compile your C source file
as a C++ file in order to call other C++ functions successfully. Each
compiler has a command line method to do this and most have a method
within their IDE to do this. If you compile your C source file as a C
file, any call that you make to a C++ function will compile correctly
if you have the proper declaration for your C++ function but will not
link because the C++ function will have name mangling applied, whereas
C knows nothing about name mangling. Needless to say compiling a C
source file that attempts to instantiate an object and call member
functions will fail at the compile stage since C knows nothing of these
C++ feartures.
Ajay Nilaver wrote:
> I am writing an application in ANSI C. I would like to know whether
> it is possible to call a C++ function from within a C program. If so,
> how can it be achieved and do all compilers support this functionality?
---
[ comp.std.c++ is moderated. To submit articles: try just posting with
]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu
]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html
]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html
]
[ Comments? mailto:std-c++-request@ncar.ucar.edu
]
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]