c++中如何為一個程序寫擴展?
老師交給我們一個任務,給定一個程序(附帶程序代碼的各個介面,但是沒有給完整的源代碼),讓我們為程序寫一下擴展功能(原本的功能是顯示感測器傳出的圖像,現在要對這段圖像進一步處理並保存),這可不可以實現?我們只知道java中寫插件是寫成plugins和features,c++的話是寫成dll文件?如果可以實現大概需要如何實現?需要學習什麼知識?
我簡單的說明下c/c++里的插件系統是怎麼運行的吧。包括.COM、Qt Plugin等各種框架的插件機制,基本都是這樣的原理。
Windows/Linux均支持通過文件名運行時載入動態鏈接庫,通過函數符號名稱獲得函數指針,故:
1、定義純虛基類作為Interface(如果有Java基礎比較好理解)。
2、把實現類封裝為dll文件,用LoadLibrary運行時載入。3、通過C API獲取插件對象實例。因為C++ ABI在不同編譯器、不同編譯器版本之間有差異,而的C ABI是穩定的。所以就可以這麼做了——1、寫一個介面類,內部都是純虛函數,用作定義對外介面
2、寫一個實例類,繼承實現這個介面。這個類不用導出。3、導出一個C函數getInstance如下extern "C" std::shared_ptr&
{
// for c++17
// return std::dynamic_pointer_cast&
return std::shared_ptr&
}
4、使用插件者,通過文件名在運行時載入dll
5、使用插件這,通過字元串"getInstance"獲取到函數指針6、運行函數指針,得到對象實例。然後就可以通過介面調用了
註:
對純虛方法的引用,可以直接編譯通過,不需要鏈接方法實現。所以使用者只需要include介面描述,就可以在代碼里使用該介面類型的指針對象了,可以順利編譯通過,不需要鏈接。然後實際運行時,就可以隨意替換實現類,然後通過配置文件或其他手段,通知程序從某個dll插件載入實例即可。使用者代碼如下:
// 載入dll
HMODULE lib = LoadLibrary("xxx.dll");
// 解析函數指針
std::function&
// 獲得對象
this-&>myPlugInstance = getInstanceFunc();
// 通過介面隨便操作咯
this-&>myPlugInstance-&>doSomething();
程序退出前別忘了通過FreeLibrary卸載dll庫
Linux下同理,只不過變成了.so庫,同樣有對應的系統API完成這些操作怎麼感覺就是直接補充源碼的意思
推薦閱讀:
※代碼里寫很多if會影響效率嗎?
※Facebook 是如何在短時間內做出 「mark safe" 這個功能的?
※怎麼證明我們的宇宙不是個程序?
※如何寫爬蟲程序爬取豆瓣網或者新浪微博里的內容?
※輪子哥的gaclib發展的怎樣?走的時什麼路線?