Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

call a C++ function from C?

1 view
Skip to first unread message

Pallav singh

unread,
Mar 29, 2009, 6:19:32 AM3/29/09
to
Hi All,

How do I call a C++ function from C?

Thanks
Pallav

Robert Hairgrove

unread,
Mar 29, 2009, 6:27:27 AM3/29/09
to

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.

Pallav singh

unread,
Mar 29, 2009, 7:00:20 AM3/29/09
to
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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

MiB

unread,
Mar 29, 2009, 8:36:21 AM3/29/09
to
On Mar 29, 1:00 pm, Pallav singh <singh.pal...@gmail.com> wrote:
> $ 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

unread,
Mar 29, 2009, 8:40:03 AM3/29/09
to
Another guess: did you really create "file2.c" or is it "file2.C" ?
I remember vaguely this made a difference for the assumed programming
language for gcc.

MiB

Pallav singh

unread,
Mar 29, 2009, 9:03:42 AM3/29/09
to

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++

can we call member functions (incl. virtual functions) of Class in C++
from C ?

MiB

unread,
Mar 29, 2009, 12:08:46 PM3/29/09
to
On Mar 29, 3:03 pm, Pallav singh <singh.pal...@gmail.com> wrote:

> 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"

James Kanze

unread,
Mar 30, 2009, 3:39:31 AM3/30/09
to
On Mar 29, 1:00 pm, Pallav singh <singh.pal...@gmail.com> wrote:
> On Mar 29, 3:27 pm, Robert Hairgrove <rhairgr...@bigfoot.com>
> wrote:> Pallav singh wrote:

> > > 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

0 new messages