• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Error

            C++博客 首頁 新隨筆 聯系 聚合 管理
              217 Posts :: 61 Stories :: 32 Comments :: 0 Trackbacks

            #

            運行時使用非標準位置/usr/lib和/lib下的庫的方式有三種:
            (1) 設置$LD_LIBRARY_PATH=庫所在目錄(多個目錄用:分隔),系統加載工具ld.so/ld-linux.so將順序搜索變量指定的目錄。例如#$LD_LIBRARY_PATH=/usr/local/mysql/lib ./test_mysql
            (2) 以root身份把庫路徑加入/etc/ld.so.conf或在/etc/ld.so.conf.d中創建特定的.conf文件,然后運行ldconfig更新/etc/ld.so.cache。例如:在/etc/ld.so.conf.d下創建文件mysql.conf寫入/usr/local/mysql/lib
            (3) 另一種辦法就是把需要的庫copy到/usr/lib或/lib,但這不是建議的方法,特別是盡量避免copy發到/lib。但這種方法可以在編譯時免去用-L選項。



            linux中動態鏈接庫的搜索順序

             (2008-12-23 10:03:20)
            標簽: 

            雜談

            linux中動態鏈接庫的搜索順序 
            //
            // by kirk,2008.11.21,文中有bug請搞緊與我聯系:-)
            //   
              

                在接手一個很古老的程序時,發現其所使用的動態庫都實在是太陳舊了,正式運行環境中部署的庫都是相適應的,而目前的開發測試環境中均是部署的新的升級版本。為了能在這些環境下開發測試,程序得能在自定義的路徑里來搜索。因此在這里復習一下linux中程序對動態鏈接庫的搜索順序,如下所述:

               1.首先查看程序文件的.dynamic 段是否包含了一個叫DT_RPATH的項(它是一個以冒號分隔的庫文件搜索目錄列表)。

               怎么設置這個選項?

               需要在編譯連接程序的時候使用-Wl,-rpath選項,假設一個程序test需要使用liblib.so庫,如下所示進行編譯連接:

                

            g++ -o test -L. -llib -Wl,rpath=./ test.cpp
             

                 這樣在執行test程序時,test便會先到./即當前目錄下查找所需要的動態庫liblib.so

                2.查找是否存在環境變量 LD_LIBRARY_PATH(它是一個以冒號分隔的庫文件搜索目錄列表)。

               怎么設置這個選項?當然是設置linux下的環境變量就可以了。

            export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./
             

                  當然,這種方法是對當前登錄生效的。如果想開機即有效,跟其它環境變量的設置也是一樣,需要修改一些配置文件。

                3.查看庫高速緩存文件 /etc/ld.so.conf ,它包含了庫名和路徑的一個對應列表,如果庫名存在,連接器就使用它對應的路徑,用這個查找方法能夠找到大部分的庫。

               怎么設置這個選項?可以直接編輯ld.so.conf加入需要查找的路徑,也可以在/etc/ld.so.conf.d目錄下的己有文件中加入路徑,或者在該目錄下新建一個文件(名字為*.conf即可),再把需要的路徑加入到該文件中。最后執行ldconfig即可生效。

                4.查找默認路徑/lib和/usr/lib,

                如果經過了以上的步驟仍然查找失敗,則將報錯并退出相關程序。

                對于前三個步驟來說,我們均是可以進行設置調整的,其中第三個步驟中的設置需要root權限才能進行,且會影響所有的程序。當使用第一、第二中的方法進行了設置調整后,我們便可以使多種版本的庫共存在同一環境下進行測試,同名也無所謂。
             *********************************************************************

            環境變量LD_LIBRARY_PATH用來指定查找共享庫時除了默認路徑之外的其他路徑。(該路徑在默認路徑之前查找)
            移植程序時的經常碰到需要使用一些特定的動態庫,而這些編譯好的動態庫放在我們自己建立的目錄里,這時我們可以設置LD_LIBRARY_PATH
            例:export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/work/lib/
            這樣就可以使用/work/lib/下的庫文件了,運行程序后系統會自動到環境變量LD_LIBRARY_PATH指定的路徑中查找其所需的庫。
            系統查找動態庫的順序
            系統先找LD_LIBRARY_PATH下的庫再找/lib and /usr/lib等路徑下的庫,還有/etc/ld.so.conf里指定的路徑(如果ld.so.conf存在),man ldconfig for more information
            [url=http://infomax/bbs/misc.php?action=viewratings&tid=111&pid=228][/url]
            使Linux啟動之后就加載LD_LIBRARY_PATH的路徑
            /etc/rc.d/rc.local文件中加入export   LD_LIBRARY_PATH="xxxxx"  即可
            如果在鏈接時使用了"-R"和"-L"選項,則相關動態庫的路徑將保存在ELF文件中,于
            是以后的運行中不再需要設置環境變量去定位動態庫。比如,有一個
            /usr/local/lib/libfoo.so,而你的bar程序需要這個libfoo.so,編譯、鏈接時最好
            這樣 :gcc -Wall -pipe -O3 -o bar -R/usr/local/lib -L/usr/local/lib bar.c -lfoo
            (#man gcc ,沒發現-R或-rpath選項,待查)


            posted @ 2015-08-18 17:42 Enic 閱讀(1116) | 評論 (0)編輯 收藏

            require("wx")
            --文檔需要結合wxWidget和wxLua來看,wxLua中明確的指定的導出的接口名字有些和wxWidget中不一樣
            --wx.wxFrame只有一個子空間的時候會自動拉伸,所以用DLG把
            dlg = wx.wxDialog(wx.NULL, wx.wxID_ANY, "wxLua例子",
                               wx.wxDefaultPosition, wx.wxSize(450,450),
                               wx.wxDEFAULT_FRAME_STYLE)
            --創建新的ID
            local ID_BTN_0 = wx.wxNewId();
            local ID_BTN_1 = wx.wxNewId();
            --使用ID創建button
            btn = wx.wxButton(dlg, ID_BTN_0, "Button", wx.wxPoint(90,0), wx.wxSize(30,60))
            btn:SetSize(wx.wxSize(30,60))
            --btn:SetPosition(wx.wxPoint(0,0))
            --設置按鈕事件
            dlg:Connect(ID_BTN_1, wx.wxEVT_COMMAND_BUTTON_CLICKED,
                function(event) 
                    wx.wxMessageBox("", "1")
                end
            )
            --C++版sdk是SetPositon,這里必須用move,很奇怪
            btn1 = wx.wxButton(dlg, ID_BTN_1, "Button1", wx.wxPoint(0,0), wx.wxSize(30,60))
            btn1:Move(wx.wxPoint(99,99))
            dlg:Move(wx.wxPoint(99,99))
            dlg:Show(true)
            wx.wxGetApp():MainLoop()
            posted @ 2015-08-14 15:43 Enic 閱讀(613) | 評論 (0)編輯 收藏

            TCP之選項TCP_KETEPALIVE
             
            KEEPALIVE機制,是TCP協議規定的TCP層(非應用層業務代碼實現的)檢測TCP本端到對方主機的TCP連接的連通性的行為。避免服務器在客戶端出現各種不良狀況時無法感知,而永遠等在這條TCP連接上。
             
            該選項可以設置這個檢測行為的細節,如下代碼所示:
            int keepAlive = 1;    // 非0值,開啟keepalive屬性
            int keepIdle = 60;    // 如該連接在60秒內沒有任何數據往來,則進行此TCP層的探測
            int keepInterval = 5; // 探測發包間隔為5秒
            int keepCount = 3;        // 嘗試探測的次數.如果第1次探測包就收到響應了,則后2次的不再發
            setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepAlive, sizeof(keepAlive));
            setsockopt(sockfd, SOL_TCP, TCP_KEEPIDLE, (void*)&keepIdle, sizeof(keepIdle));
            setsockopt(sockfd, SOL_TCP, TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval));
            setsockopt(sockfd, SOL_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount));
             
            設置該選項后,如果60秒內在此套接口所對應連接的任一方向都沒有數據交換,TCP層就自動給對方發一個保活探測分節(keepalive probe)。這是一個對方必須響應的TCP分節。它會導致以下三種情況:
                對方接收一切正常:以期望的ACK響應。60秒后,TCP將重新開始下一輪探測。
                對方已崩潰且已重新啟動:以RST響應。套接口的待處理錯誤被置為ECONNRESET。
                對方無任何響應:比如客戶端那邊已經斷網,或者客戶端直接死機。以設定的時間間隔嘗試3次,無響應就放棄。套接口的待處理錯誤被置為ETIMEOUT。
             
            全局設置可更改/etc/sysctl.conf,加上:
            net.ipv4.tcp_keepalive_intvl = 5
            net.ipv4.tcp_keepalive_probes = 3
            net.ipv4.tcp_keepalive_time = 60
             
            在程序中表現為:
            阻塞模型下,當TCP層檢測到對端socket不再可用時,內核無法主動通知應用層出錯,只有應用層主動調用read()或者write()這樣的IO系統調用時,內核才會利用出錯來通知應用層。
            非阻塞模型下,select或者epoll會返回sockfd可讀,應用層對其進行讀取時,read()會報錯。
             
            一點經驗:
            實際上我們在做服務器程序的時候,對客戶端的保活探測基本上不依賴于這個TCP層的keepalive探測機制。
            而是我們自己做一套應用層的請求應答消息,在應用層實現這樣一個功能。



            在Window上遇到這個問題,最后發現貌似只支持:
                           // 設置KEEPALIVE (開啟檢測)
            int optval = 1;
            setsockopt(m_hSocket, SOL_SOCKET, SO_KEEPALIVE, (char *) &optval, sizeof(optval));


            然后實際斷開是在主動Recv或者Send調用后才觸發的
            posted @ 2015-07-22 17:48 Enic 閱讀(218) | 評論 (0)編輯 收藏

            FileUtils::setPopupNotify()  // 圖片加載失敗后,彈出message box提示
            xpcall(main, __G__TRACKBACK__)   // xpcall( 調用函數, 錯誤捕獲函數 ); 
            package.path = package.path .. ";src/"  // ..是連字符,和win path一樣;風格,表示添加目錄src
            require("app.MyApp").new():run()  // 加載app目錄的MyApp文件,類似dofile,然后調用new方法調用默認的構造函數MyApp:ctor()在調用成員函數run
            cc.FileUtils:getInstance():addSearchPath("res/")  // 添加搜索路徑
            self:enterScene("MainScene")  // 調用 AppBase:enterScene相當于 
            //self.packageRoot = packageRoot or "app"   -- 這里的or類似C語言的?:用法,所以默認是app
            //self.packageRoot .. ".scenes." .. sceneNamelocal 
            //sceneClass = require(scenePackageName)
            cc.ui.UILabel看源代碼,發現lua是“動態類型,必須轉變cpp的思想”。cc.ui.UILabel.new實際的基類是根據參數決定的,lua代碼提供若然擴展方法,基類根據參數決定了以后還可以擁有基類的方法
            最終是通過display.newBMFontLabel等函數創建的。
            class("UILabel", function(options) return XX end),表示類UILabel繼承于后面的函數返回的對象。相當于給后面函數產生的原表附加當前給定的原表信息
             

            printInfo('run')  -- cocos也有分級日志,
            printLog(tag, fmt, ...)
            printError(fmt, ...)
            dump_value_(v)


            dump(self)  --類似php的dump函數,用于輸出復雜變量
            posted @ 2015-07-17 18:54 Enic 閱讀(206) | 評論 (0)編輯 收藏

            大神的解釋:

            Immediate Mode GUI (IMGUI)。這種類型的更多的適用于顯示區域實時刷新的程序里面,例如游戲和CAD等。
            Retained Mode GUI (RMGUI)


            用一個傳統RMGUI庫的時候,用戶往往需要顯式的初始化每一個控件對象。每個控件都是存在內存中的實體,并且每個控件都需要自己保存一部分數據(例如一個slider需要保存一個數值,Button要保存一個回調事件等),用戶還需要在一個回調函數里將控件里的數據拷貝回程序本身中(MVC模式)。

            IMGUI模式在使用上會更簡單粗暴一些。控件沒有自己的對象,不保存任何狀態,不用單獨的去實現UI和程序間數據的交換,甚至都不需要單獨為事件寫回調函數。每個控件就是一個函數,直接在程序的Draw()函數里要哪個控件就調用哪個函數就好了。



            posted @ 2015-06-25 13:49 Enic 閱讀(974) | 評論 (0)編輯 收藏

            reg add "HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers" /v "c:\windows\system32\cmd.exe" /d "RUNASADMIN" /f
            reg add "HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers" /v "C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe" /d "RUNASADMIN" /f


            問題描述:

              打開VS2012項目時,提示保存“devenv.sln”

             

            解決方法:

              找到文件:C:\Program Files (x86)\Common Files\microsoft shared\MSEnv\vslauncher.exe

              鼠標右鍵設置“兼容性”->“以管理員身份運行此程序”即可

            posted @ 2015-06-20 13:03 Enic 閱讀(210) | 評論 (0)編輯 收藏

            理解三個函數:release  retain  autorelease
            對應的有兩個計數器:ref  autoref
            autorelease是委托pool管理器在某個時候執行release

            話說cocos默認的create方法會創建完成以后立刻、馬上執行一次autorelease,行為有點詭異,而且new出來只有ref值是1
            作為規范,create以后應該馬上autorelease和init否則坑爹
             1  
             2 template <typename TVal>
             3 xcc::RefPtr<TVal> TMakeRefPtr()
             4 {
             5     TVal* pRefTem = new TVal;
             6     xcc::RefPtr<TVal> rpTem = pRefTem;
             7     rpTem->init();
             8     rpTem->autorelease();
             9 
            10     return rpTem;
            11 }

            順便放一個用于cocos的智能指針: 1 // cocos2d
             2 template<typename TCocosRefVal>
             3 class RefPtr
             4 {
             5 public:
             6     RefPtr(TCocosRefVal* pRefVal = NULL)
             7     {
             8         m_pRefVal = pRefVal;
             9         __IncRef();
            10     }
            11 
            12     RefPtr(const RefPtr<TCocosRefVal>& refVal)
            13     {
            14         m_pRefVal = pRefVal;
            15         __IncRef();
            16     }
            17 
            18     RefPtr(RefPtr<TCocosRefVal>&& refVal)
            19     {
            20         m_pRefVal = refVal.m_pRefVal;
            21 
            22         refVal.m_pRefVal = NULL;
            23     }
            24 
            25     virtual ~RefPtr()
            26     {
            27         __DecRef();
            28     }
            29 
            30     virtual const RefPtr& operator = (const RefPtr<TCocosRefVal>& refVal)
            31     {
            32         if (m_pRefVal != refVal.m_pRefVal)
            33         {
            34             Reset(refVal.m_pRefVal);
            35         }
            36 
            37         return *this;
            38     }
            39 
            40     virtual void Reset(TCocosRefVal* pRefVal = NULL)
            41     {
            42         __DecRef();
            43         m_pRefVal = pRefVal;
            44         __IncRef();
            45     }
            46 
            47     virtual bool operator == (const RefPtr<TCocosRefVal>& refVal)
            48     {
            49         return (m_pRefVal != refVal.m_pRefVal);
            50     }
            51 
            52     virtual TCocosRefVal* Get() const 
            53     {
            54         return m_pRefVal;
            55     }
            56 
            57     virtual operator TCocosRefVal*() const
            58     {
            59         return m_pRefVal;
            60     }
            61 
            62     virtual TCocosRefVal* operator -> () const
            63     {
            64         return m_pRefVal;
            65     }
            66 
            67     virtual TCocosRefVal& operator * () const
            68     {
            69         return *m_pRefVal;
            70     }
            71 
            72 protected:
            73     void __IncRef()
            74     {
            75         if (NULL != m_pRefVal)
            76         {
            77             m_pRefVal->retain();
            78         }
            79     }
            80 
            81     void __DecRef()
            82     {
            83         if (NULL != m_pRefVal)
            84         {
            85             CCAssert(m_pRefVal->retainCount() >= 1, "");
            86             m_pRefVal->release();
            87         }
            88     }
            89 
            90 private:
            91     TCocosRefVal* m_pRefVal;
            92 };
            posted @ 2015-06-06 21:28 Enic 閱讀(171) | 評論 (0)編輯 收藏

            void FixWorkingDir()
            {
            HANDLE hCurrentExe = ::GetModuleHandle(NULL);
            std::tstring strFileName;
            std::tstring strPath;
            strFileName.resize(MAX_PATH*2, 0);
            ::GetModuleFileName((HMODULE)hCurrentExe, const_cast<TCHAR*>(strFileName.data()), strFileName.size());
            auto nPosEnd = strFileName.find_last_of(_T('\\'));
            if (std::tstring::npos != nPosEnd)
            {
            strPath = strFileName.substr(0, nPosEnd);
            ::SetCurrentDirectory(strPath.c_str());
            }
            else
            {
            XASSERT_MSG(false, _T("windows did not have root path, \\ must be found"));
            }
            }
            posted @ 2015-06-06 20:58 Enic 閱讀(602) | 評論 (0)編輯 收藏

            在sqlserver 下想復制一張表的,想到oracle下直接create table xxx as select * from ....即可。
            但是結果卻是錯誤的,baidu一下發現。
            sqlserver的語法是 : select * into tablenew from tableold



            CREATE TABLE #TemTable AS SELECT * FROM PlatformCoinExchangeRecord;
            SELECT * INTO #TemTable FROM PlatformCoinExchangeRecord;
            SELECT * FROM #TemTable;
            DROP TABLE #TemTable;


            CREATE TABLE #TemTable 
            (TotalOnlineDuration bigint, 
            ByPlayDuration int, 
            TotalPlayTimes int, 
            Task30 int, 
            Task60 int, 
            Task120 int);
            INSERT INTO #TemTable exec NET_PW_GetPlayDurationTask 539;
            SELECT * from #TemTable;
            DROP TABLE #TemTable;
            臨時表可能創建后可能應為其他原因導致沒有執行到drop,這樣下次執行的時候臨時表還存在,所以創建臨時表以后最好會是做異常處理在catch中強制銷毀。
            CONTINUE HANDLE mysql可以用這個東西

             CREATE TEMPORARY table IF NOT EXISTS alarmLeveltb
             (    devID bigint not null,
                  alarmLevel bigint not null
             );

            truncate TABLE alarmLeveltb;--清空表中的數據

            如果不存在某個表就創建,mysql寫法

            IF objectproperty(object_id(@DbTableFileName),'IsUserTable') IS NOT NULL
               PRINT 'EXISTS '
            ELSE
               PRINT 'NOT EXISTS '


            貌似沒有找到直接創建的辦法,所以要約定好結果集
            posted @ 2015-05-26 11:37 Enic 閱讀(196) | 評論 (0)編輯 收藏

            在同一個sql語句中寫不同條件的Count數量
            select sum(case when Experience >= 218706 then 1 else 0 end) as '[25,+',
              sum(case when Experience >= 49065 and Experience < 218706 then 1 else 0 end) as '[20,25)',
                   sum(case when Experience >= 11773 and Experience < 49065 then 1 else 0 end) as '[15,20)',
              sum(case when Experience >= 2171 and Experience < 11773 then 1 else 0 end) as '[10,15)'
            from QPAccountsDB.dbo.AccountsInfo where IsAndroid = 0;

            http://blog.csdn.net/wangziling100/article/details/7598873

            posted @ 2015-05-20 15:49 Enic 閱讀(223) | 評論 (0)編輯 收藏

            僅列出標題
            共22頁: 1 2 3 4 5 6 7 8 9 Last 
            大香网伊人久久综合网2020| 久久性精品| 无码人妻精品一区二区三区久久 | 久久综合丝袜日本网| 青青草原综合久久大伊人导航| 久久中文字幕精品| 久久国产精品久久久| 囯产极品美女高潮无套久久久| 欧美777精品久久久久网| 很黄很污的网站久久mimi色| 丁香五月网久久综合| 99精品国产99久久久久久97| 久久人爽人人爽人人片AV| 香蕉久久久久久狠狠色| 精品久久久久久久久午夜福利| 精品国产乱码久久久久软件| 亚洲精品tv久久久久| 久久久久国产成人精品亚洲午夜| 好久久免费视频高清| 无码国内精品久久综合88| 久久婷婷色综合一区二区| 久久丫精品国产亚洲av不卡| 精品熟女少妇aⅴ免费久久| 久久久亚洲欧洲日产国码aⅴ| 性做久久久久久久| 香蕉99久久国产综合精品宅男自 | A级毛片无码久久精品免费| 国产免费久久精品丫丫| 久久婷婷五月综合色奶水99啪| 亚洲婷婷国产精品电影人久久| 国内精品久久久久久久coent| 久久久久久久久久久久中文字幕| 久久久www免费人成精品| 色诱久久av| 欧美日韩精品久久久免费观看| 中文字幕成人精品久久不卡| 国产精品免费久久久久久久久| 国产成人香蕉久久久久| 亚洲日韩中文无码久久| 伊人久久精品影院| 中文成人久久久久影院免费观看|