天天看點

關于不同程式設計語言互相調用的思考

作者:小豆君程式設計分享

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通信并不是萬能的,還需根據實際情況進行綜合考量​。

網際網路是開放開源的世界,每個有志有識之人都樂于分享,喜歡本文的你就支援一下吧

微信号:小豆君程式設計分享 (關注後,可加入小豆君交流群進行學習交流,也可第一時間看到最新文章)

頭條号:小豆君程式設計分享

繼續閱讀