从C++代码调用C函数

Dan*_*ila 81 c c++ linux extern-c

我有一个C函数,我想从C++调用.我无法使用" extern "C" void foo()"方法,因为C函数无法使用g ++编译.但它使用gcc编译很好.有关如何从C++调用函数的任何想法?

Pro*_*ica 114

像这样编译C代码:

gcc -c -o somecode.o somecode.c
Run Code Online (Sandbox Code Playgroud)

那么像这样的C++代码:

g++ -c -o othercode.o othercode.cpp
Run Code Online (Sandbox Code Playgroud)

然后使用C++链接器将它们链接在一起:

g++ -o yourprogram somecode.o othercode.o
Run Code Online (Sandbox Code Playgroud)

当你包含C函数的声明时,你还必须告诉C++编译器一个C头.所以othercode.cpp从以下开始:

extern "C" {
#include "somecode.h"
}
Run Code Online (Sandbox Code Playgroud)

somecode.h应包含以下内容:

 #ifndef SOMECODE_H_
 #define SOMECODE_H_

 void foo();

 #endif
Run Code Online (Sandbox Code Playgroud)


(我在这个例子中使用了gcc,但是任何编译器的原理都是相同的.分别用C和C++构建,然后将它们链接在一起.)

  • @Arne好点.有些人通过用[`#ifdef __cplusplus`](http://stackoverflow.com/questions/3789340/combining-c-and-c-how)在标题中包装`extern"C"来在他们的C中编写一些C++. -does-IFDEF-CPLUSPLUS工作). (7认同)
  • 我不想nipick,但最后一个代码是*声明*,而不是*定义*.但是,因为`somecode.h`可能是他在C编译中可能使用的C头,所以在头中写`extern'C"`会破坏C编译.相反,他应该在C++源文件中包含C-header周围的`extern"C". (6认同)

Arn*_*rtz 57

让我从其他答案和注释中收集点点滴滴,给你一个干净分离的C和C++代码的例子:

C部分:

foo.h:

#ifndef FOO_H
#define FOO_H

void foo(void);

#endif 
Run Code Online (Sandbox Code Playgroud)

foo.c的

#include "foo.h"

void foo(void)
{
    /* ... */
}
Run Code Online (Sandbox Code Playgroud)

用这个编译gcc -c -o foo.o foo.c.

C++部分:

bar.cpp

extern "C" {
  #include "foo.h" //a C header, so wrap it in extern "C" 
}

void bar() {
  foo();
}
Run Code Online (Sandbox Code Playgroud)

用这个编译 g++ -c -o bar.o bar.cpp

然后将它们连接在一起:

g++ -o myfoobar foo.o bar.o
Run Code Online (Sandbox Code Playgroud)

理由: C代码应该是普通的C代码,没有#ifdefs代表"也许有一天我会用另一种语言来称呼它".如果一些C++程序员调用你的C函数,那么他们的问题就是如何做到,而不是你的.如果您是C++程序员,那么C头可能不是您的,您不应该更改它,因此处理未extern "C"编码的函数名(即)属于您的C++代码.

当然,您可以自己编写一个方便的C++标头,除了将C标头包装到extern "C"声明中之外什么都不做.

  • 似乎是合法的.+1的理由 (6认同)

gx_*_*gx_ 16

我同意Falken教授的回答,但在Arne Mertz的评论之后我想给出一个完整的例子(最重要的部分是#ifdef __cplusplus):

somecode.h

#ifndef H_SOMECODE
#define H_SOMECODE

#ifdef __cplusplus
extern "C" {
#endif

void foo(void);

#ifdef __cplusplus
}
#endif

#endif /* H_SOMECODE */
Run Code Online (Sandbox Code Playgroud)

somecode.c

#include "somecode.h"

void foo(void)
{
    /* ... */
}
Run Code Online (Sandbox Code Playgroud)

othercode.hpp

#ifndef HPP_OTHERCODE
#define HPP_OTHERCODE

void bar();

#endif /* HPP_OTHERCODE */
Run Code Online (Sandbox Code Playgroud)

othercode.cpp

#include "othercode.hpp"
#include "somecode.h"

void bar()
{
    foo(); // call C function
    // ...
}
Run Code Online (Sandbox Code Playgroud)

然后你按照Falken教授的指示进行编译和链接.

这是有效的,因为在编译时gcc,__cplusplus没有定义宏,所以在预处理之后somecode.h包含的头somecode.c是这样的:

void foo(void);
Run Code Online (Sandbox Code Playgroud)

与编译时g++,那么__cplusplus 定义的,因此包括在头部othercode.cpp现在是这样的:

extern "C" {

void foo(void);

}
Run Code Online (Sandbox Code Playgroud)

  • 我不喜欢C代码中的#ifdef __cplusplus。C代码是较低的级别,如果有一天可能会从C ++代码中调用它,则不必费心。注意,如果您想为用C ++编写的库提供C绑定标头,则只能在C ++代码中使用它,而不是相反。 (4认同)
  • @ Prof.Falken当然,但这是一个定义,旨在能够提供C ++代码的“向下”兼容性,而不是C代码。 (2认同)