1. 程式人生 > >SylixOS移植ICE庫總結

SylixOS移植ICE庫總結

1 ICE 簡介

      ICE(Internet Communications Engine)是一種面向物件的中介軟體平臺,主要用於網路通訊。它為面向物件的“客戶端-伺服器”模型的應用提供了一組很好的工具和API介面。目前在全世界被應用於很多專案之中。ICE中介軟體號稱標準統一,開源,跨平臺,跨語言,分散式,安全,服務透明,負載均衡,面向物件,效能優越,防火期穿透,通訊遮蔽。因此相比Corba,DCOM,SOAP,J2EE等的中介軟體技術,自然是集眾多優點於一身,而卻沒有他們的缺點。

 
2 資源獲取

      在官網下載第三方中介軟體資源,ZeroC ICE的官方下載網站為:https://zeroc.com/downloads/ice#source。本文中使用的版本是V3.7,下載後解壓檔案,檔案目錄如圖 2.1所示。

                                                        圖2.1 Ice原始碼解壓後的檔案

      cpp/、csharp/、java/、js/、objective-c/、php/、python/等目錄包含了對應語言的Ice庫實現程式碼,config/目錄中存放控制編譯方式的相關配置檔案,slice/中存放了slice相關工具的程式碼實現。

 
3 Linux 平臺編譯

      ICE支援多種語言,並且預設情況下會編譯所有語言支援。這裡只需要移植C++相關程式碼,需要修改config/Make.rules中的supported-languages屬性,刪除不需要的語言支援只保留C++支援,如圖 3.1所示。

                                                              圖 3.1 supported-languages屬性修改

      修改配置檔案後直接在根目錄make即可進入編譯過程。為了方便後期的移植工作,這裡使用V=s選項列印編譯詳細過程並儲存到Make.log檔案中,命令:# make V=s > Make.log。編譯結束後檢視Make.log內容確認編譯成功。

 
4 移植工作

       本次移植僅移植C++支援部分的ICE主庫即libIce.so,因此只需要使用到cpp目錄下的程式碼檔案。由於是C++程式碼,在建立工程時需要選中C++工程選項。ICE主庫程式碼編譯需要依賴libbz2,也需要提前準備。

 
4.1 工程建立

      在Real-Evo IDE中建立libIce的動態庫工程。建立時選中C++工程選項並開啟專家模式,如圖 4.1所示。

                                        圖 4.1 建立工程選項

      刪除src目錄下的libIce.c檔案,匯入原始碼包中的cpp/目錄下與主庫相關的程式碼檔案。這裡需要注意的是很多程式碼檔案是編譯過程中使用slice工具建立的,因此需要在linux環境下編譯成功後才能匯出所有的檔案。其中包括目錄cpp/include/generated/Ice/、cpp/include/Ice/、cpp/include/IceUtil/、cpp/src/Ice/、cpp/src/IceUtil/。最終的目錄結構如圖 4.2所示。

                      圖 4.2 Ice程式碼目錄結構

 
4.2 配置libIce.mk

      分析Make.log中編譯libIce.so的過程,羅列出所有需要編譯的cpp檔案,並逐一加入LOCAL_SRCS中,如圖 4.3所示。

                                圖 4.3 新增cpp檔案

      新增相關的標頭檔案搜尋目錄,其中包括libbz2的工程路徑,如圖 4.4所示。

                        圖 4.4 標頭檔案搜尋路徑

 

      新增巨集配置,如圖 4.5所示。

                             圖 4.5 新增巨集配置

      新增編譯選項,如圖 4.6所示。

                             圖 4.6 新增編譯選項

      新增依賴庫,包括對libbz2庫的依賴,如圖 4.7所示。

                             圖 4.7 新增依賴庫

      開啟C++編譯擴充套件,如圖 4.8所示。

                             圖 4.8 開啟C++編譯擴充套件

 
4.3 程式碼修改

      預設編譯會出現若干編譯錯誤,需對部分程式碼進行修改,具體修改內容如下:

    修改src/ice-master/cpp/src/Ice/Cond.cpp,使用CLOCK_REALTIME模式或是時間資訊,如圖 4.9所示。

                           圖 4.9 修改獲取時間方式

    修改src/ice-master/cpp/include/IceUtil/Config.h,增加DSP大小端配置,如圖 4.10所示。

                           圖 4.10 DSP大小端配置

    修改src/ice-master/cpp/include/Ice/Service.h,DSP中interrupt符號衝突,更改為interrupt2,如圖 4.11所示。

                          圖 4.11 interrupt符號衝突

    修改src/ice-master/cpp/include/IceUtil/Config.h,消除DSP中GNUC版本錯誤,如圖 4.12所示。

                        圖 4.12消除GNUC版本錯誤

    修改src/ice-master/cpp/src/Ice/DynamicLibrary.cpp,DSP中刪除動態庫相關操作,如圖 4.13所示。

                          圖 4.13 DSP中刪除動態庫相關操作

    修改src/ice-master/cpp/src/Ice/Instance.cpp,增加標頭檔案grp.h,如圖 4.14所示。

                         圖 4.14增加標頭檔案grp.h

    修改src/ice-master/cpp/src/Ice/MetricsAdminI.cpp,DSP中增加部分缺失介面,如圖 4.15圖 4.16圖 4.17所示。

                      圖 4.15 DSP中增加部分缺失介面

                       圖 4.16 DSP中增加部分缺失介面

                        圖 4.17 DSP中增加部分缺失介面

    src/ice-master/cpp/src/Ice/Network.cpp,DSP中增加缺失的部分介面,如圖 4.18圖 4.19圖 4.20圖 4.21圖 4.22所示。

                     圖 4.18 DSP中增加缺失的部分介面

                       圖4.19 DSP中增加缺失的部分介面

                      圖 4.20 DSP中增加缺失的部分介面

                     圖 4.21 DSP中增加缺失的部分介面

                   圖 4.22 DSP中增加缺失的部分介面

    src/ice-master/cpp/src/Ice/Service.cpp,刪除fork呼叫相關程式碼,如圖 4.23所示。

                   圖 4.23刪除fork呼叫相關程式碼

    src/ice-master/cpp/src/Ice/Thread.cpp,糾正pthread_join返回值差異,如圖 4.24所示。

                  圖 4.24糾正pthread_join返回值差異

    src/ice-master/cpp/src/IceUtil/RecMutex.cpp,糾正pthread_mutex_trylock返回值差異,如圖 4.25所示。

                  圖 4.25糾正pthread_mutex_trylock返回值差異

    src/ice-master/cpp/src/IceUtil/UtilException.cpp,DSP中使用strdup代替介面__cxa_demangle,如圖 4.26所示。

                   圖 4.26 DSP中使用strdup代替介面__cxa_demangle

 
5 ICE 基本使用

      ICE應用架構是伺服器客戶端模式,包括服務端和客戶端兩部分程式碼。客戶端和伺服器程式碼由slice工具所生成的介面程式碼聯絡到一起。下面使用ICE執行一個簡單的helloworld測試例程。

5.1 生成介面程式碼

      編寫介面程式碼demo.ice,如程式清單 5.1所示。

                                                                      程式清單 5.1 demo.ice

module demo
{
    interface printer
    {        void printerstr(string msg);
    };

};

      在linux中使用ICE原始碼中編譯生成的slice工具生成介面程式碼:

 

      # cpp/bin/slice2cpp  demo.ice

      可在當前目錄中生成介面程式碼demo.cpp、demo.h。

 
5.2 建立測試工程     

      在RealEvo-IDE中建立應用工程,匯入程式碼demo.cpp、demo.h,並建立程式碼檔案server.cpp、client.cpp,內容如程式清單 5.2所示。

                                                   程式清單 5.2 server.cpp和client.cpp

client.cpp#include <Ice/Ice.h>#include <demo.h>using namespace demo;using namespace std;intmain(int argc, char * argv[]){    int status = 0;
    Ice::CommunicatorPtr ic;    try {
        ic = Ice::initialize(argc, argv);
        Ice::ObjectPrx base = ic->stringToProxy(                "SimplePrinter:default -p 10000");
        printerPrx printer = printerPrx::checkedCast(base);        if (!printer)            throw "Invalid proxy";
        printer->printerstr("Hello World!");
    } catch (const Ice::Exception & ex) {        cerr << ex << endl;
        status = 1;
    } catch (const char * msg) {        cerr << msg << endl;
        status = 1;
    }    if (ic)
        ic->destroy();    return status;
}

server.cpp#include <Ice/Ice.h>#include <demo.h>using namespace demo;using namespace std;class PrinterI : public printer {    public:        virtual void printerstr(const string & s,                const Ice::Current &);
};voidPrinterI::
printerstr(const string & s, const Ice::Current &)
{    cout << s << endl;
}intmain(int argc, char* argv[]){    int status = 0;
    Ice::CommunicatorPtr ic;    try {
        ic = Ice::initialize(argc, argv);
        Ice::ObjectAdapterPtr adapter
            = ic->createObjectAdapterWithEndpoints(                    "SimplePrinterAdapter", "default -p 10000");
        Ice::ObjectPtr object = new PrinterI;
        adapter->add(object,
                ic->stringToIdentity("SimplePrinter"));
        adapter->activate();
        ic->waitForShutdown();
    } catch (const Ice::Exception & e) {        cerr << e << endl;
        status = 1;
    } catch (const char * msg) {        cerr << msg << endl;
        status = 1;
    }    if (ic)
        ic->destroy();    return status;
}

 

      應用程式同樣使用專家模式,需建立server.mk和client.mk兩份Makefile檔案。分別加入對應的程式碼,server.mk中編譯demo.cpp、server.cpp,client.mk中編譯demo.cpp、client.cpp。並依賴ICE庫。編譯生成兩份可執行檔案,server和client。在SylixOS裝置上先後執行server和client,若在執行client時server出現“Hello World”資訊表示client成功呼叫server介面,執行結果正常。