C語言與C++編譯連線的不同點(從程式中看)
阿新 • • 發佈:2019-02-20
一:先上程式
a.h
原因是: C語言中所有的函式不能同名,而C++中函式時可以同名的,當採用上述程式設計方式a.h中遮蔽了extern void DYNAMIC_SETUP(void);,雖然在語法上a.c中的DYNAMIC_SETUP();沒有宣告,但是採用C語言編譯時,此時編譯器會以預設的方式確認程式中已存在DYNAMIC_SETUP函式。而C++總不會採用預設的方式,直接檢視是否宣告,所以就產生錯誤。 若將上述的a.h中遮蔽的extern void DYNAMIC_SETUP(void),開啟就沒有任何語法問題了,怎樣編譯都對。 設計模式中的收穫:
1.在有些動態庫中,要想複用某些函式,可以使用巨集定義函式指標的方式,在其它所有動態庫中,只需要#define 具體函式 巨集函式指標,即可,例如a.c和b.c中的應用。
2.若要是我要將程式編譯成一個動態庫,給使用者僅僅提供.h檔案,對於.h檔案中的資料結構型別無需考慮細節時,可以在.h檔案中typedef struct _DYNAMIC *PDYNAMIC;,在相應的.c檔案中進行struct _DYNAMIC的實現,如b.h和b.c。
3.對於我們要提供的動態庫,只需要提供.h檔案,此時.c檔案中的所呼叫的函式或資料型別,對於我們的提供者是不需要知道的,但是,若.h檔案中傳參的時候必須使用.c中呼叫的資料型別,此時的做法是在提供的.h檔案中單獨的宣告一下例如extern signed short CDBC_C_CHAR;,讓其編譯通過就行。而在.c檔案中進行轉換例如SQLSMALLINT CDBC_C_CHAR = SQL_C_CHAR;SQL_C_CHAR是我.c中實現所需要的呼叫動態庫中的型別。
#include <stdio.h>
//extern void DYNAMIC_SETUP(void);
void Init(void);
a.c
#include "a.h"
void Init(void)
{
DYNAMIC_SETUP();
}
b.h
#include <stdio.h>
#include <stdlib.h>
typedef struct _DYNAMIC *PDYNAMIC;
void SetUp(void);
void FUN(PDYNAMIC pDynamic);
b.c
main.c#include "b.h" struct _DYNAMIC { int nA; }; #define SetUp DYNAMIC_SETUP void SetUp(void) { printf("test-------OK\n"); PDYNAMIC pDynamic = (PDYNAMIC) malloc(sizeof(*pDynamic)); pDynamic->nA = 3; FUN(pDynamic); free(pDynamic); } void FUN( PDYNAMIC pDynamic) { printf("pDynamic->nA=%d\n", pDynamic->nA); }
#include <stdio.h>
#include "a.h"
int main()
{
printf("into main fun.........\n");
Init();
printf("out main fun.........\n");
return 0;
}
Makefile(用C++編譯程式)
此時編譯連線有問題: 原來是編譯的時候出了問題: 將上面的用C++編譯連線改為用C編譯連線,只需要將Makefile改為CC=gcc,此時沒有問題:APP = dynamic CC = g++ CFLAGS = -g SRCS = a.c b.c main.c $(APP):$(SRCS) $(CC) $(CFLAGS) $(SRCS) -o $(APP) clean: rm -rf *.o $(APP)
原因是: C語言中所有的函式不能同名,而C++中函式時可以同名的,當採用上述程式設計方式a.h中遮蔽了extern void DYNAMIC_SETUP(void);,雖然在語法上a.c中的DYNAMIC_SETUP();沒有宣告,但是採用C語言編譯時,此時編譯器會以預設的方式確認程式中已存在DYNAMIC_SETUP函式。而C++總不會採用預設的方式,直接檢視是否宣告,所以就產生錯誤。 若將上述的a.h中遮蔽的extern void DYNAMIC_SETUP(void),開啟就沒有任何語法問題了,怎樣編譯都對。 設計模式中的收穫: