2016-08-23 19 views
8

假設我在C++中有一個巨大的庫(有大量的依賴關係,它需要大約3小時才能完成GCC下的構建)。我想建立在這個lib上,但不希望在C++中這樣做,而是以更高效的語言。我怎麼才能橋接或包裝該extern lib軟件包,以便我可以在另一種語言和程序上訪問它呢?自動換行巨大的C庫爲C導入Swift/Go

語言考慮:

  • 斯威夫特
  • 轉到

是我發現的是,這兩種語言確實提供自動橋接或包裝對於C庫和代碼(我真的不知道什麼是包裝/橋接之間的區別)。所以,如果我有一些C代碼,我可以把它放在同一個Swift或Go項目中,並可以在我的項目中使用它進行簡單的導入。

但是,這對於C++代碼在兩種語言中都不起作用。所以我googled如何將C++庫轉換爲C代碼或生成autowrappers。我發現:

  1. swig.org - 對C++庫
  2. 科莫C++編譯器自動包裝 - 自動將C++到C代碼
  3. LLVM - 應該能夠採取任何輸入並將其轉換到任何輸出LLVM能夠。

問:

  1. 它甚至在該領域可用/逼真/可管理使用自動包裝上像雨燕/轉到其他語言如此巨大的LIB之上構建 ,如果 或自動橋接?
  2. 3個列出的庫/程序/框架在C++ - > C的過程中效果最好(因爲Swift和Go都提供C自動 包裝)。
  3. 到目前爲止,還有更好的替代方案嗎?
  4. 如果使用其他工具來完成包裝/橋接過程,只用「堅持使用C++」會比使用更高效的語言 更像Swift/Go嗎?

謝謝:)

免責聲明:還有手工包裹在C C++的lib的可能性但會採取工作難以承受量如此巨大的庫。

+0

除非這個圖書館是基於語言互操作性而設計的,否則這可能是一個巨大的,如果不是不可能的事情。主要挑戰將是對象生命週期管理(與宿主語言GC兼容)並將每個參數轉化爲一些簡單的C表示形式。當然,圖書館很可能是巨大的,但是它的API很小,在這種情況下你很幸運。 – marangisto

+0

SWIG功能非常強大,可以包裝相當複雜的系統,當然能夠與大型圖書館合作。它不會自動完成它,你需要調整和調整你的SWIG * .i文件,但是SWIG是解決這種問題的可靠方法,因爲它給你提供了定義原始語言如何被包裝和暴露的方法到新的調用語言。 – stderr

+0

你可能感興趣[cgogen](https://cgogen.com/) –

回答

1

Q1:它是否現實?

不現實,因爲任何大型複雜的C++ interop都會變得太複雜。自動工具可能會失敗,手動工作太難了。

Q2:什麼是最好的?

我不知道並給予A1它似乎並不重要。

Q3:另類?Q4:C++只是最好的選擇嗎?

如果您想利用來自其他語言的現有C++代碼而不考慮所涉及的語言,則複雜場景中的最佳選擇是使用混合方法。

由於非標準C++命名約定,大多數語言提供了與C而不是C++的互操作。換句話說,幾乎每種語言都提供對普通C函數的訪問,但通常不支持C++。

由於您的圖書館非常複雜,最好的解決方案將基於「Facade」模式。創建一個新的C庫並實現利用C++庫的應用程序特定邏輯。儘量設計這個庫以儘可能薄。目標不是編寫所有的業務邏輯,而是提供C++對象的C函數並調用C++函數。 GO級語言代碼然後會調用這個庫來使用下面的C++庫。這種方法與Q1方法不同。在Q1中,您嘗試在每個C++函數或對象的方法上進行一次互操作。在Facade中,您嘗試實現對應用程序唯一的C++使用場景。

由於您的目標是您的應用場景,所以使用Facade可以減少interop工作的範圍。與此同時,您可以減輕GO語言級別的C++複雜性。

例如,您需要使用C++庫讀取溫度傳感器。

在C++中,你不得不做的事:

  1. 打開文件
  2. 讀取流,直到你找到SLIP終止
  3. 閱讀一個 「記錄」
  4. 關閉文件

使用外觀,您可以創建一個名爲「readTemperature(deviceFileName)」的函數,並且C函數一次執行4個調用。

這是一個假的例子,只是爲了表明這一點。

通過外觀,您可能想要隱藏原始的C++對象,此時它變成一個小圖層。這裏的目標是保持專注和平衡您的應用程序需求與泛化,以支持您的應用程序。

有趣的是,Facade方法是一種提高互操作性能的方法。由於需要從語言運行環境進行編組並且保持它的安全,幾乎所有語言的Interop都比正常操作更昂貴。大量的互操作性調用減慢了應用程序的運行速度(我們在此討論的是數百萬人)。例如,將10個互操作呼叫合併爲1會提高性能,因爲itnerop操作的數量會減少。