• <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

            #

                今天很偶然的在cppblog上看了個博客,提到這個API,然后我想起來之前很困惑的一個問題。為什么別人的程序.exe和.dll是放在不同目錄的,而我的不能。起初我想的是也許只能用添加path這一招了。今天偶然看到這個函數順便msdn一下發現還是挺有用的。以后俺們的dll和exe也不用惡心的都丟到一起了,可以根據模塊和功能放到不同的目錄了。

               

             

            SetDllDirectory function

            9 out of 18 rated this helpful - Rate this topic

            Applies to: desktop apps only

            Adds a directory to the search path used to locate DLLs for the application.

            Syntax

            C++

            BOOL WINAPI SetDllDirectory(
              __in_opt  LPCTSTR lpPathName
            );
            
            
            Parameters
            lpPathName [in, optional]

            The directory to be added to the search path. If this parameter is an empty string (""), the call removes the current directory from the default DLL search order. If this parameter is NULL, the function restores the default search order.

            Return value

            If the function succeeds, the return value is nonzero.

            If the function fails, the return value is zero. To get extended error information, call GetLastError.

            Remarks

            The SetDllDirectory function affects all subsequent calls to the LoadLibrary and LoadLibraryEx functions. It also effectively disables safe DLL search mode while the specified directory is in the search path.

            After calling SetDllDirectory, the standard DLL search path is:

            1. The directory from which the application loaded.
            2. The directory specified by the lpPathName parameter.
            3. The system directory. Use the GetSystemDirectory function to get the path of this directory. The name of this directory is System32.
            4. The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched. The name of this directory is System.
            5. The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
            6. The directories that are listed in the PATH environment variable.

            Each time the SetDllDirectory function is called, it replaces the directory specified in the previous SetDllDirectory call. To specify more than one directory, use theAddDllDirectory function and call LoadLibraryEx with LOAD_LIBRARY_SEARCH_USER_DIRS.

            To revert to the standard search path used by LoadLibrary and LoadLibraryEx, call SetDllDirectory with NULL. This also restores safe DLL search mode based on theSafeDllSearchMode registry value.

            To compile an application that uses this function, define _WIN32_WINNT as 0x0502 or later. For more information, see Using the Windows Headers.

            posted @ 2012-06-27 22:58 Enic 閱讀(331) | 評論 (0)編輯 收藏

            boost::implicit_cast

            在stackoverflow上看到這個帖子, 于是發現了boost::implicit_cast這個小東西.

            先來看看這段代碼:

            struct top {};
            struct mid_a : top {};
            struct mid_b : top {};
            struct bottom : mid_a, mid_b {};
            
            void foo(mid_a&) {}
            void foo(mid_b&) {}
            void bar(bottom &arg) {
                foo(arg); // 想要調用"void foo(mid_a&)"
            }
            
            int main() {
                bottom x;
                bar(x);
                return 0;
            }

            是無法編譯通過的, 因為foo的重載解析有歧義. 那么把bar里的代碼改一改, 為了保持C++風格, 我們使用static_cast, 而不是C風格的轉換:

            foo(static_cast<mid_a&>(arg));

            程序編譯通過了, 運行起來也沒有問題, 然而…

            一個月以后我把bar的參數類型修改了一下:

            struct top {};
            struct mid_a : top {};
            struct mid_b : top {};
            struct bottom : mid_a, mid_b {};
            
            void foo(mid_a&) {}
            void foo(mid_b&) {}
            void bar(top &arg) {
                // ... 過了一個月, 這里已經添加了很多代碼.
                foo(static_cast<mid_a&>(arg));
            }
            
            int main() {
                top x;
                bar(x);
                return 0;
            }

            代碼依舊編譯通過, 可是運行時程序掛掉了(假設這幾個類里面有許多成員, 并且在foo里對其進行了訪問).

            發現問題了嗎? 原因就在于static_cast太強大了, 強大到可以進行”down-cast”. 于是編譯器沒有給你任何警告, 就把一個top類型的引用給強制轉換成了min_a的引用.

            這個時候輪到boost::implicit_cast出場了. 把bar里面的那句foo調用改一改:

            foo(boost::implicit_cast<mid_a&>(arg));

            于是一個月前的代碼依舊可以通過編譯, 而一個月后的代碼中的錯誤被編譯器揪出來了. 原因在于隱式類型轉換不允許”down-cast”, 只能”up-cast”.

            這里簡要說一下所謂顯式和隱式類型轉換的區別. 在C++世界的英文里, 我們說”convert”通常指”implicit convert”, 而”cast”指”explicit cast”. 隱式類型轉換好理解, 就是你寫了個a=b, 而ab不同類型, 編譯又不報錯, 就說明隱式類型轉換發生了, 類似的情況還有在函數調用的參數傳遞時. 而顯式類型轉換特指C風格的強制轉換((type)obj或者C++中等價的type(obj)), 以及C++風格的四個關鍵字(static_cast, const_cast, dynamic_cast, reinterpret_cast). 然而這個定義是相當模糊的, 比如一個int類型的x, bool(x)是顯式的, 而!!x是隱式的, 其實效果上并沒有區別, 只是字面上的不同罷了. (關于cast和convert的區別, 參見這里這里)

            所以在bar里我們需要的僅僅是一個隱式類型轉換, 然而直接把arg傳遞給foo的話會出現重載歧義, 于是我們需要告訴編譯器到底要進行哪個隱式類型轉換. 然而static_cast又太過強大, 它還能做隱式類型轉換之外的事情(up-cast), 于是在日后代碼演化的過程中留下了bug.

            于是boost::implicit_cast應運而生, 它比static_cast弱, 正如它的名字一樣, 它只能用來告訴編譯器執行什么隱式類型轉換.

            而它的代碼呢? 簡單到令人發指:

            template <typename T>
            inline T implicit_cast (typename mpl::identity<T>::type x) {
                return x;
            }

            而mpl::identity的定義也極其簡單:

            template<typename T> struct identity { typedef T type; };

            有人要問這個identity干什么用的, 看起來很累贅. 如果沒有這個identity, 像”implicit_cast(obj)”這樣的代碼也能通過編譯, 然而它其實什么也沒做, obj的類型仍然沒變. identity的存在使得函數模板的參數類型推導失效, 因為要推導出T, 首先得知道identity是什么, 而identity又是依賴于T的. 于是就形成了循環依賴, 參數類型推導就失效了. 于是編譯器就要求你顯式地指定T的類型.

            posted @ 2012-06-23 21:34 Enic 閱讀(1671) | 評論 (1)編輯 收藏

                老早就想做這個事情了,想當初做協議代碼實現的時候那個揪心啊,各種重復的代碼一遍一遍的寫。后來發現了Google的Protobuf,初次看見真TMD驚艷,,,

                吐槽下,Google的開源項目都不怎么地道,基本都是開代碼不開文檔,或文檔少的可憐,,,

                在后來項目上要用到序列化技術,而且我們的序列化工具類是鍵值對。何為鍵值對呢,,,囧,這個很難描述,先暫時記錄下我對序列化的理解。

             

            //////////////////////////////////////////////////////////////////////////////////////////////

            序列化一個抽象的概念,每個人可能理解都不同,我們約定這里談的序列是這個:

                序列化就是把一個語言成面上的依賴上下文的“對象”,變成一個精煉的語言、上下文無關的數據(可以是一塊內存,可以是一坨文件等等任何數據的載體)的動作;

            抽空百度了下,百度百科給出的解釋如下:

            序列化 (serialization) 將對象的狀態信息轉換為可以存儲或傳輸的形式的過程。

            //////////////////////////////////////////////////////////////////////////////////////////////

             

            題外話結束,繼續說我們項目上需求的鍵值對。

            剛剛的穿插序列化定義理解中可以分析出:一個序列化的數據中除了包含有原始的“數據”信息應該還包含有“數據”的描述信息。一般的需求中這個描述信息只要包含有類型信息就好了。

                比如某個“對象”序列化以后數據信息是0x63,我去,,,鬼才能知道這是什么意思,是數字?字符?還是什么別的特殊的東西?

                所以需要描述信息。比如1表示是字符,2表示是int,3表示是系統內部特定標識等等,,,

                這個偶們的鍵值對還是沒有任何關系? no no no,我們的鍵值對就是除了這個類型信息呢,還要加一個名字。偶們內部的變量不僅是有類型的還是有名字的,,,也就是說描述信息中除了有類型還要有名字,,,

             

            ////////////////////////////////////////////////////////////////////////////////////////////

            前幾天研究了下浮點怎么在網絡中傳輸。應為不同的機器或者不同的OS對浮點存儲方式是不同的。后來研究了下幾個開源的項目加上自己突然想起來大端小端int在網絡上的傳輸方式,突然發現這個問題沒有糾結的價值。標準嘛,大家統一標準就好了,誰的影響力大咱們就聽誰的,,,要擁抱世界,盡量成為一個兼容的標準。無法反抗,那就只能享受了吧,,,誰讓人家拳頭大,推廣好呢?

            ///////////////////////////////////////////////////////////////////////////////////////////

             

            恩?剛剛上面不是主題,主題是這半個月要在不影響工作的前提下好好研究代碼生成技術,其實這是為后面咱自己的序列化工具(類Google protobuf)打基礎哈,,,

            叫啥名好呢?囧,,,但愿這次咱能堅持做出來,,,

            posted @ 2012-06-23 21:01 Enic 閱讀(222) | 評論 (0)編輯 收藏

            image

            據說以前是支持的,現在是?

            怕大伙都用工具搬家搬走了去了?

             

            抱怨下,,,別無它意,,,囧啊,,,

            posted @ 2012-06-23 00:38 Enic 閱讀(95) | 評論 (0)編輯 收藏

            不在乎系統有多亂,而在乎能向前演進,棄糟粕,留精華。,,,
            posted @ 2011-09-29 00:28 Enic 閱讀(88) | 評論 (0)編輯 收藏

            這半年多時間陷入碼海,整天暈頭轉向,發現還是不行,每一套代碼都是不同的思想,而我總是追求完美,每套代碼都挑剔出各種毛病,,,

            其實回頭看來,是方向錯了,我不是要研究別人做了什么,而是我要做什么然后去看看別人怎么做的,,,

            真相再次,,,任何東西都不能脫離了需求,,,
            posted @ 2011-07-06 18:17 Enic 閱讀(142) | 評論 (0)編輯 收藏

            /*

                有兩個數組a,b,大小都為n,數組元素的值任意整形數,無序;
                要求:通過交換a,b中的元素,使[數組a元素的和]與[數組b元素的和]之間的差最小。

            */

            posted @ 2011-05-12 09:56 Enic 閱讀(685) | 評論 (0)編輯 收藏

            僅列出標題
            共22頁: First 14 15 16 17 18 19 20 21 22 
            蜜桃麻豆www久久| 久久精品免费一区二区| 2021久久精品国产99国产精品| 久久天天躁狠狠躁夜夜96流白浆 | 岛国搬运www久久| 久久中文精品无码中文字幕| 国产99久久久国产精品小说| 潮喷大喷水系列无码久久精品| 国产精品久久久天天影视香蕉| 99精品国产免费久久久久久下载| 7777久久亚洲中文字幕| 欧美久久久久久精选9999| 久久青青草原亚洲av无码app| 国产国产成人久久精品| 亚洲AV无码久久精品色欲| 久久天天躁狠狠躁夜夜av浪潮| 久久精品毛片免费观看| 久久精品国产亚洲精品| 久久精品国产91久久综合麻豆自制| 青草久久久国产线免观| 国产精品欧美久久久久天天影视| 久久亚洲精品无码aⅴ大香| 久久久黄片| 国产激情久久久久影院| 久久精品国产99国产电影网 | 狠狠色丁香婷婷综合久久来来去| 色综合久久无码中文字幕| 亚洲国产精品无码久久九九 | 日本WV一本一道久久香蕉| 99久久国产综合精品成人影院| 亚洲中文字幕无码久久综合网| 日韩中文久久| 久久久久久久久66精品片| 久久综合给合综合久久| 久久综合九色欧美综合狠狠 | 久久婷婷久久一区二区三区| 午夜欧美精品久久久久久久| 亚洲日本va午夜中文字幕久久 | 亚洲AⅤ优女AV综合久久久| 久久99国产精品99久久| 伊人久久综在合线亚洲2019|