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

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


翻譯:

我想要在C++中調用一個C語言的函數(shù)。我不能使用"extern "C" void foo()"子類的方法,因為C語言的函數(shù)使用g++編譯失敗。但是它使用gcc編譯是成功的。有沒有任何的注意關于如何在C++中調用這個函數(shù)?



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語言的函數(shù)時。所以?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函數(shù),如何做是他的問題,不是你的問題。然而如果你是一個C++程序猿,C頭文件可能不是你寫的并且你不應該修改它,所以處理函數(shù)名(如: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

? ? // ...

}

然后使用第二個答案的說明進行編譯并鏈接;

它執(zhí)行成功是因為使用gcc編譯,宏__cplusplus沒有被定義,所以包含在 somecode.cpp中的頭文件 somecode.h在預處理之后看起來像這樣:

void foo(void);

當使用g++編譯的時候,__cplusplus將會被定義,所以在 somecode.cpp中包含的頭文件現(xiàn)在像這樣:

extern "C" {

void foo(void);

}


Answers4:

這個回答是基于第二個答案的原則部分是正確的而激發(fā)的。一個提供者寫了一個庫,它曾經(jīng)支持C和C++;然而最新版本只支持C語言。在代碼中留下的指令將會具有誤導性:

#ifdef __cplusplus

extern "C" {

#endif

它花費了我好幾個小時來嘗試C++編譯。簡單的從C++中調用C是更容易的事情。

這個__cplusplus約定違反了單一責任原則。一個代碼使用這個約定就是想同時做兩件事情:

? ? 1.在C中執(zhí)行一個函數(shù);

? ? 2.執(zhí)行相同的函數(shù)在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

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容