2018年1月21日 星期日

C++ 如何引入已經寫好的 C 函式庫

C++ 如何引入已經寫好的 C 函式庫

只要告訴編譯器這一段是C語言就可以了,編譯器自己的會處理好,宣告方式如下
extern  "C"
需要把這一行加在函式的定義與宣告上,也就是 .c 與 .h 都要加上,可以使用括號涵蓋一個範圍
extern  "C" {
// Your code
}
如果這個函式庫是你正在開發的,還需需要被C的編譯器編譯就補上宏定義,讓代碼可以同時讓C與C++編譯器編譯
#ifdef  __cplusplus
extern  "C" {
#endif

// Your code

#ifdef  __cplusplus
}
#endif

範例

下面在C++檔案內引入C的檔案
// fileName : fun.h
#pragma once

#ifdef  __cplusplus
extern  "C" {
#endif

void fun();

#ifdef  __cplusplus
}
#endif
// fileName : fun.c
#ifdef  __cplusplus
extern  "C" {
#endif

#include <stdlib.h>
#include <stdio.h>    
void fun() {
    printf("c file \n");
}

#ifdef  __cplusplus
}
#endif
// fileName : main.cpp
#include <iostream>
#include "fun.h"

int main(int argc, char const *argv[]){
    fun();
    return 0;
}

原因

C++ 多了重載的功能,對於函式名稱的解析規則與C不一樣
對於C來說
fun(int, int); 與 fun(char, char); 都是解析成同一個 _foo
對C++來說則是解析成
fun(int, int); -> _fun_int_int
fun(char, char); -> _fun_char_char
這也正是可以多載的原因,如果加了修飾子則可以使用C的規則解析。
比如說上面的範例的C檔案沒有加入 extern “C” ,C++檔案直接引入 .h,這時候 fun.h 裡面的宣告是複製貼到 main.cpp 上,解析是看檔名,該份檔案是.cpp會被解析成 _fun_int_int ,則 fun.c 編譯的時候則被解析成 _fun 這時候名字就對不上了。

參考

沒有留言:

張貼留言