1 思考曆程
最近有些加我微信的朋友私信我說,如何通過Qt調用python,如何通過java調用C++動态庫等一系列的不同語言互相調用的問題。
關于這個問題,你隻需要在百度搜尋框中搜尋,就會出來很多相關的文章,但真正應用到自己系統中時,往往會遇到很多問題,比如環境、系統、相容、版本問題等。這經常會耗費好幾天的時間才能真正解決。
那對于這些問題,有沒有一個通用的解決方案呢,我也思考了良久,現在也想通了一些,故分享給大家,也是對我自己做一次總結。
在開始之前,我想先總結下不同語言互相調用的方法
1)Qt調用Python:需要加載python庫,及包含python的頭檔案
2)Python調用動态庫:需導入ctypes子產品,需要将python的資料類型轉化為C或C++中的資料類型
3)Java調用動态庫:需使用jni進行調用,也會涉及到資料類型互相轉換
...
面對如此多的複雜方式,我們應該怎樣才能提出一個通用的解決方案呢。
現在我們試想如果把兩種程式設計語言設想成是兩個應用程式,那麼應用程式之間的互動應該如何處理,即程序之間應如何處理,這使我想到了IPC(程序間通信)
好,既然是IPC,那麼IPC總共包含以下幾種方式
IPC |
匿名管道 |
有名管道 |
隊列 |
共享記憶體 |
socket |
除去socket外,其它ipc方式,都會頻繁地涉及到資源同步問題,而使用socket我們可以有效避免這類問題,且不需要處理複雜的資料類型轉換。
為此,我們再進一步推演,既然是socket,那麼有沒有現成的架構或設計方式可以供我們參考,答案肯定是有的,那就是現在非常流行的C/S架構(不明白的可百度自行搜尋)
2 為什麼如此做參考上圖:
我們将傳統的語言互相調用的模式,轉化成了C/S架構,總結起來可以有如下優點
1)屏蔽環境問題:不同語言互相調用的複雜環境問題,隻需部署好各自的運作環境。例如:
a. 語言版本不相容
b. 作業系統32位或64位相容性問題
c. 調用的第三方庫對環境有依賴
2)屏蔽語言資料類型差異:不需要對不同語言所支援的資料類型做轉化,使用通用Json語言進行序列化或反序列化即可。例如:
a. 有符号和無符号之間的轉換
b. 字元串寬窄字元轉換
c. 不同編碼類型的轉換
3)應用隔離:兩種語言是互相隔離的,在架構設計時,隔離性是必須要考慮到的。例如:
a. 當被調用的C++程式需要調用一個較新的功能或引用一個新的動态庫,而使用此功能必須需要更新C++版本
b. 被調用方如果崩潰,會引起調用方崩潰
c. 可單獨進行監控、自動化mock測試、代碼優化
4)不必部署在同一機器上:socket連接配接可使兩個應用單獨部署,如果後期需要,可以不改變代碼的情況下靈活切換。例如:
a. 調用其它語言一般是要進行複雜運算,為提高運算速度和穩定性,可将此部分靈活地切換到伺服器上
b. 有些應用要求的磁盤或記憶體空間有限,需要将某些功能移動到伺服器上,這樣可有效減少體積
c. 某些應用并不想暴露過多的細節給客戶,為安全考慮,可将這部分移動到伺服器上單獨部署
對于此種方式,有些同學可能會擔心性能上的問題,一般情況下此種結構是部署在同機上的,對于現代硬體速度,這種差異幾乎是可以忽略不計的。
3 如何做
既然好處這麼多,那如何做呢
3.1 選擇通信協定
既然是socket,那首先要考慮用什麼協定,直接使用原生的socket,小豆君還是不太建議,這裡你得處理很多跟應用無關的東西。鑒于是同機應用互相調用,使用websocket還是比較好的選擇。
在不同的語言環境中,大家可以直接在百度搜尋就可以看到很多關于websocket的調用方法,這裡就不介紹了。
3.2 路由表
既然是服務端,就要對外提供接口,起初我們會這樣定義:
{
"interface": "getUserName",
"params": {
"userName": "wang"
}
} {
"interface": "setSystemInfo",
"params": {
"sysName": "win"
}
}
但是當你的接口增多時,這樣的方式就會很混亂,是以你要将衆多的接口進行分類整理,這時候就可以使用路由表,路由表可以使用“/”進行分隔,如
{
"interface": "users/get/by/name",
"params": {
"userName": "wang"
}
} {
"interface": "sys/set/all",
"params": {
"sysName": "win"
}
}
注意此路由表不必與實際目錄真實對應,此處僅表示邏輯對應
3.3 版本号
為了進行相容,你應該在你的接口中增加版本号等相容性資訊,如果不填,則可以使用預設設定
3.4 為你的接口增加mock
增加mock單元測試,可以使你很容易地構造測試用例,并且保證代碼有足夠的穩定性
最後,每當我們工作中遇到問題時,百度出來的解決方案往往不适用目前環境,為此我們可能會花掉好幾天的時間來解決問題,這是一個非常煩心的事情
為解決這種困境,小豆君會針對每個主題問題彙總到一篇文章中,當大家遇到問題時,隻需要在我的這篇文章中查找即可解決,省時省力,同時也可以快速擷取知識,提高工作效率,升職加薪(*^▽^*)
好了,關于今天的分享就到這裡了,socket通信并不是萬能的,還需根據實際情況進行綜合考量。
網際網路是開放開源的世界,每個有志有識之人都樂于分享,喜歡本文的你就支援一下吧
微信号:小豆君程式設計分享 (關注後,可加入小豆君交流群進行學習交流,也可第一時間看到最新文章)
頭條号:小豆君程式設計分享