導航:首頁 > 源碼編譯 > bcb編譯成lib

bcb編譯成lib

發布時間:2024-09-17 13:44:36

❶ #pragma的常用參數

Message 參數能夠在編譯信息輸出窗口中輸出相應的信息,這對於源代碼信息的控制是非常重要的。其使用方法為: #pragmamessage(消息文本)當編譯器遇到這條指令時就在編譯輸出窗口中將消息文本列印出來。
當我們在程序中定義了許多宏來控制源代碼版本的時候,我們自己有可能都會忘記有沒有正確的設置這些宏,此時我們可以用這條指令在編譯的時候就進行檢查。假設我們希望判斷自己有沒有在源代碼的什麼地方定義了_X86這個宏可以用下面的方法 #ifdef_X86#pragmamessage(_X86macroactivated!)#endif當我們定義了_X86這個宏以後,應用程序在編譯時就會在編譯輸出窗口裡顯示「_X86 macro activated! 」。我們就不會因為不記得自己定義的一些特定的宏而抓耳撓腮了。 (比較常用)
只要在頭文件的最開始加入這條指令就能夠保證頭文件被編譯一次,這條指令實際上在VC6中就已經有了,但是考慮到兼容性並沒有太多的使用它。
#pragma once是編譯相關,就是說這個編譯系統上能用,但在其他編譯系統不一定可以,也就是說移植性差,不過現在基本上已經是每個編譯器都有這個定義了。
#ifndef,#define,#endif這個是C++語言相關,這是C++語言中的宏定義,通過宏定義避免文件多次編譯。所以在所有支持C++語言的編譯器上都是有效的,如果寫的程序要跨平台,最好使用這種方式 #pragma hdrstop表示預編譯頭文件到此為止,後面的頭文件不進行預編譯。BCB可以預編譯頭文件以加快鏈接的速度,但如果所有頭文件都進行預編譯又可能占太多磁碟空間,所以使用這個選項排除一些頭文件。
有時單元之間有依賴關系,比如單元A依賴單元B,所以單元B要先於單元A編譯。你可以用#pragma startup指定編譯優先順序,如果使用了#pragma package(smart_init) ,BCB就會根據優先順序的大小先後編譯。 #pragmacomment(...)該指令將一個注釋記錄放入一個對象文件或可執行文件中。
常用的lib關鍵字,可以幫我們連入一個庫文件。
每個編譯程序可以用#pragma指令激活或終止該編譯程序支持的一些編譯功能。例如,對循環優化功能: #pragmaloop_opt(on)//激活#pragmaloop_opt(off)//終止有時,程序中會有些函數會使編譯器發出你熟知而想忽略的警告,如「Parameter xxx is never used in function xxx」,可以這樣: #pragmawarn—100//#100intinsert_record(REC*r){/*functionbody*/}#pragmawarn+100//#100backon函數會產生一條有唯一特徵碼100的警告信息,如此可暫時終止該警告。
每個編譯器對#pragma的實現不同,在一個編譯器中有效在別的編譯器中幾乎無效。可從編譯器的文檔中查看。 #pragmapack(n)和#pragmapop()structsample{chara;doubleb;};當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) #pragmacomment(comment-type,[commentstring])comment-type是一個預定義的標識符,指定注釋的類型,應該是compiler,exestr,lib,linker之一。
comment string是一個提供為comment-type提供附加信息的字元串。
注釋類型:
1、compiler:
放置編譯器的版本或者名字到一個對象文件,該選項是被linker忽略的。
2、exestr:
在以後的版本將被取消。
3、lib:
放置一個庫搜索記錄到對象文件中,這個類型應該是和comment string(指定你要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了 介紹
用#pragma data_seg建立一個新的數據段並定義共享數據,其具體格式為: #pragmadata_seg(shareddata)HWNDsharedwnd=NULL;//共享數據#pragmadata_seg()-----------------------------------------------------------------
1,#pragma data_seg()一般用於DLL中。也就是說,在DLL中定義一個共享的有名字的數據段。最關鍵的是:這個數據段中的全局變數可以被多個進程共享,否則多個進程之間無法共享DLL中的全局變數。
2,共享數據必須初始化,否則微軟編譯器會把沒有初始化的數據放到.BSS段中,從而導致多個進程之間的共享行為失敗。例如, #pragmadata_seg(MyData)intg_Value;//.#pragmadata_seg()//DLL提供兩個介面函數:intGetValue(){returng_Value;}voidSetValue(intn){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,這就實現了跨進程之間的數據通信。 #pragma region是Visual C++中特有的預處理指令。它可以讓你折疊特定的代碼塊,從而使界面更加清潔,便於編輯其他代碼。折疊後的代碼塊不會影響編譯。你也可以隨時展開代碼塊以進行編輯等操作。
格式: #pragmaregionname#pragmaendregioncomment使用示例如下: #pragmaregionVariablesHWNDhWnd;constsize_tMax_Length=20;//othervariables#.如上邊所示,需要折疊的代碼必須包含在#pragma region和#pragma endregion之間。#pragma region和#pragma endregion之後可以添加一些用來注釋的文字。當你折疊代碼塊後,這些文字會顯示在折疊的位置。
折疊代碼塊的方法:如同Visual C++中折疊函數、類、命名空間,當代碼被包含在如上所述的指令之間後,#pragma region這一行的左邊會出現一個「-」號,單擊以折疊內容,同時「-」號會變成「+」號,再次單擊可以展開代碼塊。
此預編譯指令在Visual Studio 2005及以上版本可以使用。但是在Visual Studio 2005中,當#pragma region之後包含類似「1st」這類的文字,會導致「error C2059: syntax error : 'bad suffix on number'」的編譯錯誤。避免使用數字或者將數字與字母分離可以解決這個問題。

❷ 如何使用C++Builder編譯Delphi使用Obj文件

一直以來,Delphi 都可以用命令行 dcc32 ProjectName.dpr 對項目進行編譯鏈接,非常方便,Delphi對項目文件的參數配置處理的很簡單,便於閱讀處理起來也很直觀,編譯的中間文件也很簡單(dcu,dcp)。

而C++Builder就沒那麼幸運了,因為包含了C++的特徵,各種編譯的中間文件:lib,obj,res,map,tds。後來新版又增加了一些預編譯文件:ilc,ild,ilf,...,pch,#00,...等等等等,各種搜索路徑(Include Path,Library Path,Browse Path...),要是用bcc32及ilink32手工進行編譯鏈接,命令的參數都足夠寫上大半天。幸好,在舊版C++Builder中,如果要用命令行編譯BCB項目,只要將bpr文件轉換為mak文件,再使用make命令進行編譯鏈接也比較方便,不需要過多的處理:

[plain] view plainprint?

bpr2mak -oProject1.mak Project1.bpr

make -fProject1.mak

自從Delphi/C++Builder開始使用 MSBuild* 編譯系統後(好像是RAD Studio 2006開始,具體忘記了),Delphi項目在保存為dpr的同時,也會保存一份dproj的項目文件,dpr依舊沿用舊格式,dproj 則以MSBuild規范以XML格式保存,除了可以用舊方式命令行編譯dpr外,也可以用:

[plain] view plainprint?

msbuild.exe /t:Rebuild /p:Config=Debug ProjectName.dproj

進行編譯,但msbuild必須設定一些環境變數,RAD Studio自帶了一個命令行工具已經做好了這些,其實就是設定了以下幾個環境變數($(BDS)in svars.bat):

[plain] view plainprint?

@SET BDS=C:EmbarcaderoRAD Studio7.0

@SET BDSCOMMONDIR=C:UsersPublicDocumentsRAD Studio7.0

@SET FrameworkDir=C:WindowsMicrosoft.NETFrameworkv2.0.50727

@SET FrameworkVersion=v2.0.50727

@SET FrameworkSDKDir=

@SET PATH=%FrameworkDir%;%FrameworkSDKDir%;%PATH%

@SET LANGDIR=EN

C++Builder則又更杯具了一些,bpr2mak.exe工具已經沒有了,所以只能採用MSBuild進行命令行編譯。更加杯具的是,隨著Delphi和BCB被多次轉賣收購,新版本的發布似乎總會有各種各樣的Bug,比如手頭的RAD Studio 2009進行命令行編譯,Delphi正常,BCB則報出超過100個錯誤,類似如下:

[plain] view plainprint?

C:EmbarcaderoRAD Studio7.0BinCodeGear.Cpp.Targets(2175,3): error : Error: Unresolved external '__fastcall Strhlpr::UnicodeFree(System::UnicodeString&)' referenced from C:EMBARCADERORAD STUDIO7.0LIBDEBUGVCLE.LIB|ustring

C:EmbarcaderoRAD Studio7.0BinCodeGear.Cpp.Targets(2175,3): error : Error: Unresolved external 'Typinfo::BooleanIdents' referenced from C:EMBARCADERORAD STUDIO7.0LIBDEBUGVCLE.LIB|vclinit

檢查了一下發現編譯過程(bcc32.exe)沒有問題,只是在ilink32.exe鏈接過程中報錯,在IDE中打開此項目進行編譯,查看Message->Output窗口,比較兩者的ilink32命令行參數,發現兩者有兩個地方有明顯差異,一個是IDE生成的命令中沒有類似 C:EmbarcaderoRAD Studio7.0libENdebug 的路徑(指的是EN這個目錄,去除上面rsvars.bat中的@SET LANGDIR=EN 就可以避免產生這樣的搜索路徑) ,但是雖然這個目錄不存在,也應該不至於導致出錯。第二個差異是缺少了rtl.bpi和vcl.bpi的附加obj參數,解決辦法是在$(BDS)in目錄中找到 CodeGear.Cpp.Targets 文件,用記事本打開,搜索字元「memmgr.lib「,在前面加上"rtl.bpi;vcl.bpi" (用;分隔,不含引號),一共有兩處要修改。或者查找 "c0w32",在後面加上 "rtl.bpi;vcl.bpi",只有一處修改 —— 因為IDE的命令行中 rtl.bpi vcl.bpi是在c0w32和memmgr.lib中間的。—— (注意:在XE2中,加在c0w32後面已經不管用了,編譯會報另一個錯誤VCL.BPIW.OBJ不存在,Targets文件有很大變化,可能參數的位置變動過了,導致與其他參數混在一起,所以還是加到memmgr.lib處更加合理)。

一些組件包比如DevExpress的Package,沒有dproj或者cproj 項目文件,只能通過IDE進行轉換,但坑爹的是bpk在好幾個版本以前(CRS 2007?)已經不支持bpk項目,根本打不開也談不上轉換了,但它其實是一個make文件,可惜用make命令編譯還是要出錯,不想去研究了。總之,BCB永遠活在Delphi的陰影下。

閱讀全文

與bcb編譯成lib相關的資料

熱點內容
java與sqlserver資料庫連接 瀏覽:21
鐵路解壓視頻全過程 瀏覽:442
主備核心交換機如何連接伺服器 瀏覽:704
白金卡哪個app最靠譜 瀏覽:666
本田汽車空調壓縮機保險絲 瀏覽:155
康佳led47r5500pdf通病 瀏覽:821
cad圓相切命令 瀏覽:69
bmp文件夾打開 瀏覽:502
u盤裝系統文件下載到哪個文件夾 瀏覽:21
es系統封裝教程程序員大本營 瀏覽:523
程序員聚餐喝什麼酒好 瀏覽:608
編譯程序生成安裝文件 瀏覽:955
linux查看usb設備 瀏覽:284
安卓怎麼禁止app充值 瀏覽:559
動盪對加密貨幣的影響 瀏覽:358
國家反詐app哪裡看注冊時間 瀏覽:563
打孔式文件夾怎麼裝視頻 瀏覽:29
php怎麼學比較好 瀏覽:381
python中關於函數調用 瀏覽:362
debian系統命令行如何排序 瀏覽:407