簡單的使用Swig將C++標準庫編寫的動態庫提供給C#使用方法
處於工作要求,需要把Qt和opencv編寫的動態庫提供給客戶的的csharp程式使用,因此花時間研究了這個方法,本人的方法比較簡單,就是提供一個C++標準的動態庫作為橋,可以在動態庫中再呼叫opencv和qt編寫的動態庫,降低了耦合度,也有利於我自己修改介面而不需要別人干預;
來說步驟了
1.首先需要配置swig 官網下載
http://www.swig.org/
官網上下載了最新的安裝包 這個是我下載的地址,3.0.12
https://sourceforge.net/projects/swig/files/swigwin/swigwin-3.0.12/swigwin-3.0.12.zip/download?use_mirror=jaist
下載完成後,配置程式目錄到系統環境,主要是為了減少後期輸入
我的是win10 配置如下
配置好環境變數對於win10來說可以直接使用,其他的可能需要重啟,如果你vs開著,需要關閉vs,重新開一下
2.編寫 C++橋 動態庫,本人使用vs2017,所以和vs2015稍微有一點區別
先新建空專案
接著修改工程屬性為動態庫
接著建立一個類對應的資原始檔,其中標頭檔案定義在下一個截圖
類中用到的引數定義在下面的檔案中,這樣子寫是為了給大家一個參照,如何引入其他標頭檔案,但是請勿在你的最外層類的標頭檔案中包含非標準c++的型別標頭檔案,因為後面找不到無法轉換,切記只能是包含C++標準;網上有的把類宣告成為匯出,方便其他c++也可以編譯呼叫,這個我測試了一下,比較麻煩,需要引入window.h和後面新增window.i配置,所以就不這麼玩,這個玩法只是為了給c#做橋
如果你想包含其他的非標準標頭檔案,想使用呢 ,方法如下:
請忽略我的標頭檔案找不到錯誤,只是為了示例 ,這個也是C++常用的,前置宣告,然後只是使用類的指標或者引用;
在cpp用引用標頭檔案,加速編譯和防止重複引用;
程式碼寫好了,接下來就該配置關於swig的轉換規則
3.編寫轉換的配置檔案
我個人理解的配置檔案的意義就是替換對應的類、函式、型別成為其他語言中通用的資料型別
說明一下,上面的module後面跟的名稱需要和你動態庫名稱相同(去掉dll),也要和後面命令中的一致
標頭檔案包含順序需要按照你自己程式碼中的先後使用順序來,因為我最先在gloabal**中使用了標準c++的型別,因此需要先包含對應標頭檔案,之後包含我自己的標頭檔案,注意看格式,具體為什麼要這麼做,請參考官方文件,我是下載了官方的pdf,後面也會上傳;
4.接著一部就是呼叫命令,你可以選擇到你的工程目錄呼叫cmd執行命令,也可以在vs編譯後新增命令,後者比較方便而已
我使用後者
我的命令寫在txt文件中,方便檢視
命令依次是
呼叫環境變數中的swig 程式
將c++
轉換到 c#
生成中間檔案
名稱如***wrapper
生成的c#的檔案,都使用名稱空間 ***namespace
呼叫的swig配置替換模板檔案是 *.i
注意,請勿使用回車
將上述命令複製貼上到vs的配置下
開始編譯吧
,編譯後會在工程目錄下生成一堆cs檔案和一個cpp檔案,就是命令中的中間檔案
最後把中間檔案新增到工程,再次編譯生成對應的dll庫
完成了一半
接下來建立C#控制檯程式測試
vs2017是沒有嚮導的,因此直接生成了工程
依次完成下面圈著的地方:
複製c++工程生成的cs檔案到c#工程下
使用剛才定義的名稱空間引入我們的型別資料
編寫測試程式碼
編譯
等等還不能執行的
我們編譯了剛剛的檔案,但是執行時候需要c++編譯的動態庫,所以要到c++工程生成的dll拷貝到c#bin目錄下
好了執行測試如下程式碼
結果如上
好了以上就是全部的步驟,可能你會想,如果你已經有了一個C++或者C的第三方庫,這麼可以掉用介面呢;
C語言的話swig提供了extern的方法,具體看官方手冊,但是我自己寫的話就直接引入他的標頭檔案在cpp裡面過載實現呼叫就可以了;
如果是其他的如qt,opencv的庫,也是差不多,在cpp檔案中引入,對應的寫函式編寫,切記不要把第三方的標頭檔案引入到你的橋的標頭檔案中,這個肯定不能轉換成功
下載點選下面:
示例程式碼 地址 CpptoCsharp.zip