翻译:Call a C function from C++ code

Stack overflow地址:Call a C function from C++ code - Stack Overflow


翻译:

我想要在C++中调用一个C语言的函数。我不能使用"extern "C" void foo()"子类的方法,因为C语言的函数使用g++编译失败。但是它使用gcc编译是成功的。有没有任何的注意关于如何在C++中调用这个函数?



Answers1:

编译C代码像这样:

gcc -c -o somecode.o somecode.c

编译C++代码像这样:

g++ -c -o othercode.o othercode.cpp

然后一起链接它们,使用C++ linker:

g++ -o yourprogram somecode.o othercode.o

你不得不告诉C++编译器一个C语言的头文件来了,在你include一个C语言的函数时。所以 othercode.cpp这么开始:

extern "C" {

#include "somecode.h"

}

somecode.h应该包括像下面的东西:

#ifndef SOMECODE_H_

#define SOMECODE_H_

void foo();

#endif

(在这个例子中,我使用了gcc编译器,原则上来说其他任何编译器是一样的。分开编译C和C++,然后一起链接它们)


Answers2:

其他让我来收集一下其他回答和评论的点点滴滴,给你一个示例,清晰的分开C和C++代码:

C模块:

foo.h:

#ifndef FOO_H

#define FOO_H

void foo(void);

#endif

foo.c

#include "foo.h"

void foo(void)

{

    /* ... */

}

使用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();

}

使用g++ -c -o bar.o bar.cpp编译。

然后把他们链接到一起:

g++ -o myfoobar foo.o bar.o

原则:C代码需要是纯净的C代码,没有 #ifdef对于“可能有一天我会从这里调用其他语言”。如果一个C++程序猿调用了你的C函数,如何做是他的问题,不是你的问题。然而如果你是一个C++程序猿,C头文件可能不是你写的并且你不应该修改它,所以处理函数名(如:extern C)是属于你的代码。

你可能会写一个你自己方便的C++头,什么也不做只是用extern C封装了一个C头文件。


Answers3:

我同意第一个答案,但是看了第二个答案的评论之后我想要给出一个完整的示例(#ifdef __cplusplus是非常重要的)

somecode.h

#ifndef H_SOMECODE

#define H_SOMECODE

#ifdef __cplusplus

extern "C" {

#endif

void foo(void);

#ifdef __cplusplus

}

#endif

#endif /* H_SOMECODE */

somecode.c

#include "somecode.h"

void foo(void)

{

    /* ... */

}

othercode.hpp

#ifndef HPP_OTHERCODE

#define HPP_OTHERCODE

void bar();

#endif /* HPP_OTHERCODE */

othercode.cpp

#include "othercode.hpp"

#include "somecode.h"

void bar()

{

    foo(); // call C function

    // ...

}

然后使用第二个答案的说明进行编译并链接;

它执行成功是因为使用gcc编译,宏__cplusplus没有被定义,所以包含在 somecode.cpp中的头文件 somecode.h在预处理之后看起来像这样:

void foo(void);

当使用g++编译的时候,__cplusplus将会被定义,所以在 somecode.cpp中包含的头文件现在像这样:

extern "C" {

void foo(void);

}


Answers4:

这个回答是基于第二个答案的原则部分是正确的而激发的。一个提供者写了一个库,它曾经支持C和C++;然而最新版本只支持C语言。在代码中留下的指令将会具有误导性:

#ifdef __cplusplus

extern "C" {

#endif

它花费了我好几个小时来尝试C++编译。简单的从C++中调用C是更容易的事情。

这个__cplusplus约定违反了单一责任原则。一个代码使用这个约定就是想同时做两件事情:

    1.在C中执行一个函数;

    2.执行相同的函数在C++中。

这就好像同时想写美国和英国的英语一样。这是没必要的通过#ifdef __thequeensenglish spanner #elif __yankeeenglish wrench #else的宏,这将使代码很难读到#endif在哪里。

对于简单的代码和库使用 ifdef __cplusplus约定可能会很好的工作;但是,对于复杂的库最好选择一种语言或者另一种坚持下去。支持一种语言将会更少的去维护比尝试支持多种语言。

下面是我对第一个答案的修改记录,来让它可以在 Ubuntu上编译。

foo.h:

#ifndef FOO_H

#define FOO_H

void foo(void);

#endif

foo.c

#include "foo.h"

#include

void foo(void)

{

    // modified to verify the code was called

    printf("This Hello World was called in C++ and written in C\n");

}

bar.cpp

extern "C" {

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

}

int main() {

  foo();

  return(0);

}

Makefile

# -*- MakeFile -*-

# dont forget to use tabs, not spaces for indents

# to use simple copy this file in the same directory and type 'make'

myfoobar: bar.o foo.o

    g++ -o myfoobar foo.o bar.o

bar.o: bar.cpp

    g++ -c -o bar.o bar.cpp

foo.o: foo.c

    gcc -c -o foo.o foo.c

你可能感兴趣的:(翻译:Call a C function from C++ code)