1. 程式人生 > >C/C++混合程式設計 #ifdef __cplusplus extern "C" {...}

C/C++混合程式設計 #ifdef __cplusplus extern "C" {...}

C用gcc方式編譯;C++用g++方式編譯。

C/C++混合程式設計需要關鍵字extern。

c++呼叫c比較簡單,只需要extern; ||  而c呼叫c++則需要考慮c++的函式過載等功能,需要使用 #ifdef __cplusplus extern "C" {...}

一、extern“C”的作用(最重點)

    1. extern "C"的真實目的是實現類C和C++的混合程式設計extern “C”是由C++提供的一個連線交換指定符號,用於告訴C++這段程式碼是C函式。extern “C”後面的函式不使用的C++的名字修飾,而是用C這是因為C++編譯後庫中函式名會變得很長,與C生成的不一致,造成C++不能直接呼叫C函式。

二、extern“C”與__cplusplus(主要是c呼叫C++時使用)

#ifdef __cplusplus
extern "C" {
#endif
//·················
//之間是需要指明用C方式編譯的程式碼;原本屬於C++的程式碼
//·················
#ifdef __cplusplus
}
#endif

    cplusplus即"C++",用於C++文件的標頭檔案中,上面程式碼的意思是:如果是C++檔案(*.cpp)字尾,則使用extern “C”,在C++專案中應用的非常廣泛。即使用gcc編譯器編譯,函式名為C型別如_foo

三、對例項進行編譯說明

1、 C++呼叫C

有由C語言編寫的add()、sub()程式,並將其生成靜態庫:

//add.h
#ifndef __ADD_H__
#define __ADD_H__
int add(int, int);
#endif /* __ADD_H__ */

//add.c
#include "add.h"
int add(int a, int b)
{
    return a + b;
}
//------------------------------------------------
//sub.h
#ifndef __SUB_H__
#define __SUB_H__
int sub(int, int);
#endif /* __SUB_H__ */

//sub.c
#include <stdio.h>
#include "sub.h"
int sub(int a, int b)
{
    printf("%d - %d = %d\n", a, b, a - b);
    return 0;
}

編譯生成靜態庫lib**.a或動態庫lib**.so

#靜態庫
$ gcc -c add.c
$ gcc -c sub.c
$ ar cqs libadd.a *.o

#動態庫
$ gcc -shared -fPIC *.o -o libadd.so

但是主函式呼叫這兩個函式時是用C++編寫的->>>>>>>>>>> 用g++編譯

//main.cpp
#include "add.h"
#include "sub.h"
#include <stdio.h>
int main(void)
{
    int c = add(1, 6);
    sub(8, 2);
    printf("c = %d\n", c);
    return 0;
}

用g++編譯,則會報錯----->>>>>>>>>>>>>>>>未定義add、sub函式

所以要加上關鍵字extern,main函式修改如下:將用C語言編寫的標頭檔案用關鍵字extern的花括號括起來

//使得add.h、sub.h裡面的程式碼用c語言的方式去編譯
extern "C"{
#include "add.h"
#include "sub.h"
}
#include <stdio.h>
int main(void)
{
    int c = add(1, 6);
    printf("c = %d\n", c);
    return 0;
}

2、 C呼叫C++