<menu id="w8yyk"><menu id="w8yyk"></menu></menu>
  • <dd id="w8yyk"><nav id="w8yyk"></nav></dd>
    <menu id="w8yyk"></menu>
    <menu id="w8yyk"><code id="w8yyk"></code></menu>
    <menu id="w8yyk"></menu>
    <xmp id="w8yyk">
    <xmp id="w8yyk"><nav id="w8yyk"></nav>
  • 網站首頁 > 物聯資訊 > 技術分享

    預處理指令中#Pragma

    2016-09-28 00:00:00 廣州睿豐德信息科技有限公司 閱讀
    睿豐德科技 專注RFID識別技術和條碼識別技術與管理軟件的集成項目。質量追溯系統、MES系統、金蝶與條碼系統對接、用友與條碼系統對接 在所有的預處理指令中,#Pragma 指令可能是最復雜的了,它的作用是設定編譯器的狀態或者是指示編譯器完成一些特定的動作。#pragma指令對每個編譯器給出了一個方法,在保持與C和C++語言完全兼容的情況下,給出主機或操作系統專有的特征。依據定義,編譯指示是機器或操作系統專有的,且對于每個編譯器都是不同的。
    其格式一般為: #pragma Para。其中Para 為參數,下面來看一些常用的參數
    1.message 參數   Message 參數能夠在編譯信息輸出窗口中輸出相應的信息,這對于源代碼信息的控制是非常重要的。其使用方法為:   #pragma message(“消息文本”)   當編譯器遇到這條指令時就在編譯輸出窗口中將消息文本打印出來。   當我們在程序中定義了許多宏來控制源代碼版本的時候,我們自己有可能都會忘記有沒有正確的設置這些宏,此時我們可以用這條指令在編譯的時候就進行檢查。假設我們希望判斷自己有沒有在源代碼的什么地方定義了_X86這個宏可以用下面的方法   #ifdef _X86   #pragma message("_X86 macro activated!")   #endif   當我們定義了_X86這個宏以后,應用程序在編譯時就會在編譯輸出窗口里顯示“_X86 macro activated! ”。我們就不會因為不記得自己定義的一些特定的宏而抓耳撓腮了。 2.code_seg   另一個使用得比較多的pragma參數是code_seg。格式如:   #pragma code_seg( ["section-name"[,"section-class"] ] )   它能夠設置程序中函數代碼存放的代碼段,當我們開發驅動程序的時候就會使用到它。 3.#pragma once   (比較常用)   只要在頭文件的最開始加入這條指令就能夠保證頭文件被編譯一次,這條指令實際上在VC6中就已經有了,但是考慮到兼容性并沒有太多的使用它。   #pragma once是編譯相關,就是說這個編譯系統上能用,但在其他編譯系統不一定可以,也就是說移植性差,不過現在基本上已經是每個編譯器都有這個定義了。   #ifndef,#define,#endif這個是C++語言相關,這是C++語言中的宏定義,通過宏定義避免文件多次編譯。所以在所有支持C++語言的編譯器上都是有效的,如果寫的程序要跨平臺,最好使用這種方式 4.#pragma hdrstop   #pragma hdrstop表示預編譯頭文件到此為止,后面的頭文件不進行預編譯。BCB可以預編譯頭文件以加快鏈接的速度,但如果所有頭文件都進行預編譯又可能占太多磁盤空間,所以使用這個選項排除一些頭文件。   有時單元之間有依賴關系,比如單元A依賴單元B,所以單元B要先于單元A編譯。你可以用#pragma startup指定編譯優先級,如果使用了#pragma package(smart_init) ,BCB就會根據優先級的大小先后編譯。 5.#pragma resource   #pragma resource "*.dfm"表示把*.dfm文件中的資源加入工程。*.dfm中包括窗體外觀的定義。 6.#pragma warning   #pragma warning( disable : 4507 34; once : 4385; error : 164 )   等價于:   #pragma warning(disable:4507 34) // 不顯示4507和34號警告信息   #pragma warning(once:4385) // 4385號警告信息僅報告一次   #pragma warning(error:164) // 把164號警告信息作為一個錯誤。   同時這個pragma warning 也支持如下格式:   #pragma warning( push [ ,n ] )   #pragma warning( pop )   這里n代表一個警告等級(1---4)。   #pragma warning( push )保存所有警告信息的現有的警告狀態。   #pragma warning( push, n)保存所有警告信息的現有的警告狀態,并且把全局警告等級設定為n。   #pragma warning( pop )向棧中彈出最后一個警告信息,   在入棧和出棧之間所作的一切改動取消。例如:   #pragma warning( push )   #pragma warning( disable : 4705 )   #pragma warning( disable : 4706 )   #pragma warning( disable : 4707 )   //.......   #pragma warning( pop )   在這段代碼的最后,重新保存所有的警告信息(包括4705,4706和4707)。 7.pragma comment   pragma comment(...)   該指令將一個注釋記錄放入一個對象文件或可執行文件中。   常用的lib關鍵字,可以幫我們連入一個庫文件。   每個編譯程序可以用#pragma指令激活或終止該編譯程序支持的一些編譯功能。例如,對循環優化功能:   #pragma loop_opt(on) // 激活   #pragma loop_opt(off) // 終止   有時,程序中會有些函數會使編譯器發出你熟知而想忽略的警告,如“Parameter xxx is never used in function xxx”,可以這樣:   #pragma warn —100 // Turn off the warning message for warning #100   int insert_record(REC *r)   { /* function body */ }   #pragma warn +100 // Turn the warning message for warning #100 back on   函數會產生一條有唯一特征碼100的警告信息,如此可暫時終止該警告。   每個編譯器對#pragma的實現不同,在一個編譯器中有效在別的編譯器中幾乎無效。可從編譯器的文檔中查看。   #pragma pack(n)和#pragma pop()   struct sample   {   char a;   double b;   };   當sample結構沒有加#pragma pack(n)的時候,sample按最大的成員那個對齊;   (所謂的對齊是指對齊數為n時,對每個成員進行對齊,既如果成員a的大小小于n則將a擴大到n個大小;   如果a的大小大于n則使用a的大小;)所以上面那個結構的大小為16字節.   當sample結構加#pragma pack(1)的時候,sizeof(sample)=9字節;無空字節。   (另注:當n大于sample結構的最大成員的大小時,n取最大成員的大小。   所以當n越大時,結構的速度越快,大小越大;反之則)   #pragma pop()就是取消#pragma pack(n)的意思了,也就是說接下來的結構不用#pragma pack(n)   #pragma comment( comment-type ,["commentstring"] )   comment-type是一個預定義的標識符,指定注釋的類型,應該是compiler,exestr,lib,linker之一。   commentstring是一個提供為comment-type提供附加信息的字符串。   注釋類型:   1、compiler:   放置編譯器的版本或者名字到一個對象文件,該選項是被linker忽略的。   2、exestr:   在以后的版本將被取消。   3、lib:   放置一個庫搜索記錄到對象文件中,這個類型應該是和commentstring(指定你要Linker搜索的lib的名稱和路徑)這個庫的名字放在Object文件的默認庫搜索記錄的后面,linker搜索這個這個庫就像你在命令行輸入這個命令一樣。你可以在一個源文件中設置多個庫記錄,它們在object文件中的順序和在源文件中的順序一樣。如果默認庫和附加庫的次序是需要區別的,使用Z編譯開關是防止默認庫放到object模塊。   4、linker:   指定一個連接選項,這樣就不用在命令行輸入或者在開發環境中設置了。   只有下面的linker選項能被傳給Linker.   /DEFAULTLIB ,/EXPORT,/INCLUDE,/MANIFESTDEPENDENCY, /MERGE,/SECTION   (1) /DEFAULTLIB:library   /DEFAULTLIB 選項將一個 library 添加到 LINK 在解析引用時搜索的庫列表。用 /DEFAULTLIB指定的庫在命令行上指定的庫之后和 .obj 文件中指定的默認庫之前被搜索。忽略所有默認庫 (/NODEFAULTLIB) 選項重寫 /DEFAULTLIB:library。如果在兩者中指定了相同的 library 名稱,忽略庫 (/NODEFAULTLIB:library) 選項將重寫 /DEFAULTLIB:library。   (2)/EXPORT:entryname[,@ordinal[,NONAME]][,DATA]   使用該選項,可以從程序導出函數,以便其他程序可以調用該函數。也可以導出數據。通常在 DLL 中定義導出。entryname是調用程序要使用的函數或數據項的名稱。ordinal 在導出表中指定范圍在 1 至 65,535 的索引;如果沒有指定 ordinal,則 LINK 將分配一個。NONAME關鍵字只將函數導出為序號,沒有 entryname。   DATA 關鍵字指定導出項為數據項。客戶程序中的數據項必須用 extern __declspec(dllimport)來聲明。   有三種導出定義的方法,按照建議的使用順序依次為:   源代碼中的 __declspec(dllexport).def 文件中的 EXPORTS 語句LINK 命令中的 /EXPORT 規范所有這三種方法可以用在同一個程序中。LINK 在生成包含導出的程序時還創建導入庫,除非生成中使用了 .exp 文件。   LINK 使用標識符的修飾形式。編譯器在創建 .obj 文件時修飾標識符。如果 entryname以其未修飾的形式指定給鏈接器(與其在源代碼中一樣),則 LINK 將試圖匹配該名稱。如果無法找到唯一的匹配名稱,則 LINK 發出錯誤信息。當需要將標識符指定給鏈接器時,請使用 Dumpbin 工具獲取該標識符的修飾名形式。   (3)/INCLUDE:symbol   /INCLUDE 選項通知鏈接器將指定的符號添加到符號表。   若要指定多個符號,請在符號名稱之間鍵入逗號 (,)、分號 (;) 或空格。在命令行上,對每個符號指定一次 /INCLUDE:symbol。   鏈接器通過將包含符號定義的對象添加到程序來解析 symbol。該功能對于添包含不會鏈接到程序的庫對象非常有用。用該選項指定符號將通過 /OPT:REF 重寫該符號的移除。   我們經常用到的是#pragma comment(lib,"*.lib")這類的。#pragma comment(lib,"Ws2_32.lib")表示鏈接Ws2_32.lib這個庫。 和在工程設置里寫上鏈入Ws2_32.lib的效果一樣,不過這種方法寫的 程序別人在使用你的代碼的時候就不用再設置工程settings了 8.#pragma data_seg   #pragma data_seg介紹[1]   用#pragma data_seg建立一個新的數據段并定義共享數據,其具體格式為:   #pragma data_seg ("shareddata")   HWND sharedwnd=NULL;//共享數據   #pragma data_seg()   -----------------------------------------------------------------   1,#pragma data_seg()一般用于DLL中。也就是說,在DLL中定義一個共享的有名字的數據段。最關鍵的是:這個數據段中的全局變量可以被多個進程共享,否則多個進程之間無法共享DLL中的全局變量。   2,共享數據必須初始化,否則微軟編譯器會把沒有初始化的數據放到.BSS段中,從而導致多個進程之間的共享行為失敗。例如,   #pragma data_seg("MyData")   int g_Value; // Note that the global is not initialized.   #pragma data_seg()   DLL提供兩個接口函數:   int GetValue()   {   return g_Value;   }   void SetValue(int n)   {   g_Value = n;   }   然后啟動兩個進程A和B,A和B都調用了這個DLL,假如A調用了SetValue(5); B接著調用int m = GetValue(); 那么m的值不一定是5,而是一個未定義的值。因為DLL中的全局數據對于每一個調用它的進程而言,是私有的,不能共享的。假如你對g_Value進行了初始化,那么g_Value就一定會被放進MyData段中。換句話說,如果A調用了SetValue(5); B接著調用int m = GetValue(); 那么m的值就一定是5,這就實現了跨進程之間的數據通信。
    本文摘自百度百科. 更詳細的信息請參考:http://blog.csdn.net/wrq147/archive/2009/07/31/4398674.aspxRFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成
    最近免费观看高清韩国日本大全