How do I call a C++ function from C?
Thanks
Pallav
Is the function located in an external library?
The easiest way to do this would be to compile a separate module as C++
which provides wrappers for the C++ functions, exporting them as "extern
C ...". Then you can link your C code to those functions and don't have
to worry about name decoration issues.
file1.cc
extern "C" void func(int );
void func(int i)
{
printf(" C++ function called %d \n", i);
}
file2.c
#include <stdio.h>
void func(int);
void cc(int i)
{ func(i); }
int main()
{
cc(1);
return 0;
}
$ g++ -g file1.cc file2.c
: In function `_Z2cci':
: undefined reference to `func(int)'
collect2: ld returned 1 exit status
The compiler decorates function "cc" to "_Z2cci" which makes me guess
it compiles file2.c as C++ code (expecting decorated naming of "func",
too).
Try:
g++ -g file1.cc
gcc -g file2.c
g++ file1.o file2.o
- maybe this cures the problem.
MiB
MiB
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++
can we call member functions (incl. virtual functions) of Class in C++
from C ?
> can we call member functions (incl. virtual functions) of Class in C++
> from C ?
For non-static member functions, you need an object for that kept by
the C++ wrapper.
Note, the following code is just a sketch. Essentially, a repository
of created objects is kept and is
referenced by handles of type integer.
I am sure it can be done much nicer and needs extra work for thread
safety and fault tolerance. The performance
can be improved by using a std::vector<> instead of a map but you may
need to keep track of used and free entries
in the repository.
The scheme works with polymorphism, though - if the factory function
"CreateMyClassObject()", or extra functions
added for this purpose, create objects of derived classes, virtual
member functions are called properly.
Make sure the MyBaseClass destructor is virtual to avoid pitfalls
here.
-------------------------------------------------------------------------------------------------
ExampleUsage.c:
#include "Wrapper.h"
...
int handle = CreateMyClassObject();
printf( "%d\n", ExampleMemberFunc( handle, 42 ) );
DestroyMyClassObject( handle );
-------------------------------------------------------------------------------------------------
MyClass.hpp:
class MyClass {
public:
int ExampleMemberFunc( int x );
};
-------------------------------------------------------------------------------------------------
Wrapper.h:
extern "C" {
int CreateMyClassObject(); // you need to add parameters as your
constructor requires.
void DestroyMyClassObject( int handle );
int ExampleMemberFunc( int handle, int x ); // note the added handle
param.
}
-------------------------------------------------------------------------------------------------
Wrapper.cc:
#include "MyClass.hpp" // defines the class you want to wrap.
#include <map>
static std::map<int, MyClass*> myclassrepository;
extern "C" {
int CreateMyClassObject() { // you need to add parameters as your
constructor requires.
myclassrepository[ myclassrepository.size() ] = new MyClass();
return myclassrepository.size() - 1; // index of created object.
}
void DestroyMyClassObject( int handle ) {
std::map<int, MyClass*>::iterator p = myclassrepository.find
( handle );
if ( p != myclassrepository.end() ) {
delete p->second;
myclassrepository.remove( p );
}
}
int ExampleMemberFunc( int handle, int x ) {
std::map<int, MyClass*>::iterator p = myclassrepository.find
( handle );
if ( p == myclassrepository.end() ) {
// Error Handling, no object for this handle.
return 0;
}
return p->second->ExampleMemberFunc( x );
}
} // extern "C"
> > > How do I call a C++ function from C?
> > Is the function located in an external library?
> > The easiest way to do this would be to compile a separate
> > module as C++ which provides wrappers for the C++ functions,
> > exporting them as "extern C ...". Then you can link your C
> > code to those functions and don't have to worry about name
> > decoration issues.
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> i am getting following error
> file1.cc
> extern "C" void func(int );
> void func(int i)
> {
> printf(" C++ function called %d \n", i);
> }
> file2.c
> #include <stdio.h>
> void func(int);
> void cc(int i)
> { func(i); }
> int main()
> {
> cc(1);
> return 0;
> }
> $ g++ -g file1.cc file2.c
> : In function `_Z2cci':
> : undefined reference to `func(int)'
> collect2: ld returned 1 exit status
As has already been pointed out, this is probably due to file2.c
being compiled as C++, and not as C. Another point to be aware
of is that if there is any C++ code in the program, the function
main must be compiled as C++. For something this simple, it
probably won't cause a problem, but it's undefined behavior, and
often doesn't work. (Also, you're missing some includes in
file1.cc.)
--
James Kanze (GABI Software) email:james...@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34