美文网首页
翻译:Call a C function from C++ co

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

作者: 东东东东东东丶 | 来源:发表于2018-06-11 10:12 被阅读0次

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

          本文链接:https://www.haomeiwen.com/subject/kmensftx.html