1. 程式人生 > >C語言與C++編譯連線的不同點(從程式中看)

C語言與C++編譯連線的不同點(從程式中看)

 一:先上程式 a.h
#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
#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);
}
main.c
#include <stdio.h>

#include "a.h"

int main()
{
    printf("into main fun.........\n");
    Init();
    printf("out main fun.........\n");

    return 0;
}
Makefile(用C++編譯程式)
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編譯連線,只需要將Makefile改為CC=gcc,此時沒有問題:
原因是: 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中實現所需要的呼叫動態庫中的型別。