简体   繁体   中英

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.

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.

最好/最简单的方法是将所需的c ++位包装在ac接口中,然后从c源文件中调用c接口。

如果我们只是要发布链接,相对于FAQ ,我更喜欢FQA

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::string s 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.)

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM