關於C和C++混編的一些心得

qq_30000801發表於2020-11-18

C和C++混編

專案要求將檢測識別程式和跟蹤程式結合起來使用,識別暫時使用的是海思demo自帶的RFCN識別程式,跟蹤用的是KCF跟蹤演算法。這其中RFCN是純C的程式碼,而KCF是C++程式碼,並且編譯和執行的時候需要連結OPENCV的動態庫。

因為程式執行過程中肯定需要呼叫海思sdk的一些靜態庫檔案或者其他相關檔案,並且海思VI-VPSS-VENC-VO的一系列執行流程已經被涵蓋到RFCN的例子中去了,所以最簡單的辦法當然是以RFCN的demo為主並在上面做改進,在RFCN執行並檢測到目標之後呼叫KCF提供的函式來進行跟蹤。

簡單地記錄一下大概過程:

因為C++有類這種東西,而C語言沒有,所以方便起見對KCF的類和類內函式進行封裝,KCFTracker類封裝成結構體KCFTracker_s,結構體中唯一的成員是KCFTracker類的一個實體tracker;類內函式外層封裝一層函式,引數提供指向KCFTracker_s的指標和類內函式需要的引數:

struct KCFTracker_s{
	KCFTracker tracker;
};


struct KCFTracker_s* createTracker(){
	return new KCFTracker_s;
}


void KCFInit(struct KCFTracker_s* pTracker,int xMin,int yMin,int width,int height,unsigned char* dataAddr){
 	Mat newMat;
 	RGB2Mat(dataAddr,&newMat,width,height);
 	pTracker->tracker.init(Rect(xMin,yMin,width,height),newMat);
}

這一層封裝也就是為C提供方便使用的介面,也需要使用g++來編譯。

因為C和C++對函式的識別符號的編譯方式不同,所以封裝之後的函式需要在標頭檔案的宣告中加上extern "C"的關鍵字,大概是這麼使用的:

#ifndef _KCFWRAPPER_H_
#define _KCFWRAPPER_H_



struct KCFTracker_s;

#ifdef __cplusplus
extern "C"{
#endif

struct KCFTracker_s* createTracker();

void KCFInit(struct KCFTracker_s* pTracker,int xMin,int yMin,int width,int height,unsigned char* dataAddr);
int* KCFUpdate(struct KCFTracker_s* pTracker,unsigned char* dataAddr,int width,int height);
void ReleaseTrakcer(struct KCFTracker_s** ppTracker);

#ifdef __cplusplus
};
#endif




#endif

注意哦,#ifdef __cplusplus這裡的下劃線是有兩段的,如果不小心只寫一段的話g++編譯不會報錯,但是在和RFCN的目標檔案連結的時候是會報錯的,編譯器會指出找不到相關函式的定義。

編譯順序是分別用g++和gcc編譯好相應的程式碼,然後用gcc來連結。編譯時記得記上-lstdc++ 連結c++的庫。

相關文章