C++混合編程之idlcpp教程(一)

    我是C++語言的忠實擁躉,因爲在上學時經歷了資源匱乏的DOS時代,對C/C++這種更加接近硬件的語言由衷的喜好。一直以來也是已C++做爲工做的語言,對別的語言那是不屑一顧。在java火爆流行的時候,沒有去深刻了解過。如今看實際上是一種損失,若非如此這篇博文或許能早幾年就寫出來了。而後因爲工做的關係學了一點C#,在看到關於元數據的時候,萌生了在C++中實現相似功能的念頭。後來接觸過一些腳本語言,發現藉助元數據是實現C++和腳本語言混合編程的好辦法。html

     最初的時候,我嘗試使用模板來實現這樣的功能。通過一段時間的實踐後,發現有些問題不易解決,並且用起來也不太方便,寫了一半就放棄了。後來聯想到微軟使用idl這種接口描述語言來定義COM接口,決定使用相似的方法。大致就是定義一種接口描述語言,經過相應的編譯器生成對應的C++頭文件以及元數據描述代碼,同時提供一個運行時庫做爲使用這些元數據的基礎。這個編譯器就是idlcpp,意爲用接口描述語言生成C++代碼,固然此處的idl不是微軟的idl,只不過因意義類似,也用了一樣的英文簡寫。java

    此idl語言到目前爲止支持以下概念:命名空間,類和結構,數據成員,屬性,方法,靜態成員,虛函數,函數重載,運算符重載,多重繼承,枚舉,模板等。其中關鍵字大部分照抄的C++,因此乍看起來比較像C++代碼。python

    除了idlcpp這個編譯器外,還有一個基礎的運行時庫,以及針對不一樣的腳本語言相應的插件(目前只有lua和python),使用的開發工具是Visual Studio 2015,對非MS平臺不太熟悉,因此暫時編譯器只支持Windows平臺(用到了一些Windows特有的函數)。不過運行時庫沒有用到特定平臺的功能,較易移植到其餘平臺。此外還寫了一些示例代碼。上述全部代碼託管在github上:https://github.com/fdyjfd/idlcpp/,另外還建了一個網站:http://idlcpp.org/ 目前網站還沒什麼內容,之後慢慢去豐富。git

    下面進入正題,先從工具的使用開始。github

Idlcpp命令行工具

    Idlcpp能夠從github上下載代碼編譯獲得,另外我也在網上放了一份已經編譯好的執行文件,能夠從 http://files.cnblogs.com/files/fdyjfd/idlcpp.zip 下載直接使用。若要本身編譯idlcpp,請先從github上獲取源代碼。源代碼結構以下:編程

    其中idlcpp目錄下是idlcpp的源代碼。paf目錄下是基礎運行時庫與腳本插件的代碼。tutorials下是一些示例教程。目錄bin是用來放置編譯生成的dll及exe文件的,示例的lua和python腳本也放在這裏。windows

    編譯idlcpp要用到第三方工具flex和bison。這兩個工具能夠從 https://sourceforge.net/projects/gnuwin32/ 下載。安裝這兩個工具後將其所在目錄設置到環境變量Path中,以便編譯時能夠找到它們。編譯成功後會在bin目錄下生成idlcpp.exe。也能夠下載我上傳的以編譯好的zip壓縮包,將其解壓到bin目錄下,而後將bin目錄也設置到環境變量Path中;或者將其解壓到windows目錄下供後面使用。函數

idlcpp經過編譯接口描述文件(默認擴展名爲.i),生成4個C++代碼文件,分別是:工具

1. 相應的頭文件(默認擴展名爲.h)。開發工具

2. 內置函數的實現文件(默認擴展名爲.ic)。

3. 元數據包裝類的頭文件(默認擴展名爲.mh)。

4. 元數據包裝類的實現文件(默認擴展名爲.mc)。

    運行cmd,進入idlcpp所在目錄,運行命令idlcpp –h,結果以下圖所示:

 

各選項含義爲:

-h  顯示幫助信息。

-ld  在生成的頭文件中加入 #line 指令,用於編譯器發現錯誤時正肯定位到 .i文件中的對應位置。

-pc  指定運行時庫pafcore頭文件所在的路徑。

-mp 元數據包裝類的名字是根據對應類型的名字以及所在的命名空間生成的,此選項用於指定生成的元數據包裝類型名的後綴,默認值爲」_Type」。

-sp  用於生成子類代理類名字的後綴,默認值爲」_Proxy」。子類代理類用於模擬腳本繼承C++類型進而重寫虛函數的功能。

-ic  指定內置函數的實現文件名的後綴,默認爲」.ic」。

-mh  指定元數據頭文件的後綴,默認爲」.mh」。

-mc  指定元數據實現文件的後綴,默認爲」.mc」。

-em  在Visual C++中,需用__declspec(dllexport)和__declspec(dllimport)處理dll中導出函數的情形,通常狀況下用一個宏定義上述二者,在生成的元數據代碼中也須要導出一些函數到dll中,此時idlcpp把此處定義的宏插到相應的代碼處。

 -I 將指定路徑加入#import命令的搜索路徑中。

編譯paf

用Visual Studio 2015打開解決方案文件paf\build\vs2015\paf.sln

 

paf 中有3個工程,分別爲:

1.  pafcore,這是基礎的運行時庫,提供了元數據的實現。至關於.Net中的System.Reflection或者java中的java.lang.reflect。

2.  paflua,這是lua的插件,用於pafcore和lua之間的交互,使用lua語言能夠經過這個插件訪問用戶導出的各類功能。

3.  pafpython,這是python的插件,用於pafcore和python之間的交互,使用python語言能夠經過這個插件訪問用戶導出的各類功能。 

在pafcore工程中除了C++代碼文件以外,還有許多idl的代碼文件(擴展名爲.i),以下圖:

 

這些文件都是須要用idlcpp編譯的。此處經過Custom Build Tool設置編譯命令和選項,查看任意一個.i文件的屬性,入下圖所示:

 

 

在Visual Studio中能夠經過屬性文件簡化Custom Build Tool的設置,pafcore所使用的屬性文件在paf\build\vs2015\pafcore\pafcore.props。

設定好idlcpp.exe的路徑以便系統能夠找到它(好比設置環境變量Path或將其複製到Windows目錄下)後便可編譯pafcore工程。

工程paflua依賴lua,先從lua官網下載源文件編譯後,再設置合適的頭文件以及庫文件路徑,便可編譯。

工程pafpython依賴python,先從python官網下載源文件編譯後,再設置合適的頭文件以及庫文件路徑,便可編譯。

以上三個工程都會編譯爲Dll文件,默認放置在bin目錄下。如果release版,文件名分別爲pafcore.dll, paflua.dll和pafpython.dll。如果debug版,文件名分別爲pafcore_d.dll, paflua_d.dll和pafpython_d.dll。

到如今爲止,準備工做已經完成,下次開始介紹 tutorials 下的各個例子程序。

Lua語言的例子從這 C++混合編程之idlcpp教程Lua篇(2) 開始

Python語言的例子從這 C++混合編程之idlcpp教程Python篇(2) 開始

相關文章
相關標籤/搜索