domlao
domlao

Reputation: 16029

Call a C++ function from a C source code

Is it possible to call a C++ function from a C source code?

Please advice.

Many thanks.

Upvotes: 1

Views: 1738

Answers (5)

quamrana
quamrana

Reputation: 39414

If you want to call functions from C code and you want to #include the header file for the prototype, then the C compile must not see any extern "C" statements.

See other SO questions, eg like this.

Upvotes: 0

wkl
wkl

Reputation: 80031

You will want to look into the extern C construct.

From the link:

 // This is C++ code

 // Declare f(int,char,float) using extern "C":
 extern "C" void f(int i, char c, float x);

 ...

 // Define f(int,char,float) in some C++ module:
 void f(int i, char c, float x)
 {
   ...
 }

You can also declare/define multiple functions using the extern C construct are like so:

Declaring and d multiple functions using extern C

extern "C"
{
   void func1();
   void func2();
}

extern "C"
{
   void func1()
   {
      /// do something
   }

   void func2()
   {
      // do something else
   }
}

You can even wrap #include declarations with extern "C" like so:

   extern "C"
   {
      #include "myHeader.h"
   }

The above will cause everything in fictional header myHeader.h to have C linkage, but can cause problems with nested includes - basically, do not use this construct if you can directly modify the header file yourself. It is a last resort technique.

Caveats

As Jack Kelly (thanks Jack Kelly!) mentions, be sure that if your C++ code involves exceptions, that they are handled in your function and are not allowed to propagate to C.

Functions defined with extern "C" linkage cannot be overloaded, as C does not allow multiple functions with the same name.

Your C and C++ code have to be compiled with similar compilers, as they need to agree on types, calling conventions, etc.

References, because I can't do this alone

Thanks to the commenters.

Upvotes: 9

jrockway
jrockway

Reputation: 42704

I needed to do something like this, and saved my experiment to github: http://github.com/jrockway/cplusplus-binding-examples

libexample++ is the C++ library we are trying to bind to C. libexample is the C binding; you compile it with the C++ compiler, but it produces a library with demangled names that C (and everything else) can call. It also converts std::strings to char *s, and so on.

Finally, there is examplehs which is a Haskell binding to libexample, and example-perl, a perl binding to libexample. This lets you see how to call C++ from other languages, via C.

If I was going to do it again, I would have used a different name for the C struct and the C++ class, as the FQA recommends.

(Also, for the sake of "why do it this way", it's because only the C++ compiler knows how to call C++ functions. When you define a function foo, the compiler compiles this to a function that the rest of the runtime toolchain thinks is called something like foo_4dskjaf3874hdfas. This means that only the C++ compiler can generate code that calls it, since only the C++ compiler knows what the function is actually called. When you use extern "C", then the C++ compiler does not "mangle" the name, and then there is no naming problem. You can dlopen the library, call foo, and get the function you expect.

You don't always have to go through C when binding C++ to other languages; Perl will happily invoke the C++ compiler and make it do the demangling, but GHC Haskell won't. So I always go through C when I am trying to bind a C++ library to something, because it's very easy to bind everything else to C. Anything to C++ is hit-or-miss.)

Upvotes: 2

justin
justin

Reputation: 104708

it's best/easiest to wrap the c++ bits you need in a c interface, then call the c interface from the c source files.

Upvotes: 3

Jack Kelly
Jack Kelly

Reputation: 18667

If we're just going to post links, I prefer the FQA to the FAQ.

Upvotes: 2

Related Questions