1. 程式人生 > >vc連結靜態庫的時候要注意的問題

vc連結靜態庫的時候要注意的問題

1、VC編譯選項 多執行緒 (/MT) 多執行緒除錯 (/MTd) 多執行緒 DLL  (/MD) 多執行緒除錯 DLL  (/MDd) 2、C執行時庫                     庫檔案 Single thread(static link) ML           libc.lib Debug single thread(static link) MLd      libcd.lib MultiThread(static link) MT           libcmt.lib Debug multiThread(static link) MTd      libcmtd.lib MultiThread(dynamic link) MD           msvcrt.lib Debug multiThread(dynamic link) MDdmsvcrtd.lib  3. 各種 C執行時庫的區別
(1)靜態連結的單執行緒庫 靜態連結的單執行緒庫只能用於單執行緒的應用程式, C 執行時庫的目的碼最終被編譯在應用程式的二進位制檔案中。通過 /ML編譯選項可以設定 Visual C++ 使用靜態連結的單執行緒庫。 (2)靜態連結的多執行緒庫 靜態連結的多執行緒庫的目的碼也最終被編譯在應用程式的二進位制檔案中,但是它可以在多執行緒程式中使用。通過 /MT編譯選項可以設定 Visual C++ 使用靜態連結的多執行緒庫。 (3)動態連結的執行時庫 動態連結的執行時庫將所有的 C 庫函式儲存在一個單獨的動態連結庫 MSVCRTxx.DLL 中,MSVCRTxx.DLL處理了多執行緒問題。使用 /MD 編譯選項可以設定 Visual C++ 使用動態連結的執行時庫。 /MDd 、 /MLd 或 /MTd 選項使用 Debug runtime library( 除錯版本的執行時刻函式庫 ),與 /MD 、 /ML 或 /MT 分別對應。 Debug 版本的 Runtime Library包含了除錯資訊,並採用了一些保護機制以幫助發現錯誤,加強了對錯誤的檢測,因此在執行效能方面比不上 Release版本。  4、下面是msdn關於Visual C++編譯器選項的說明:
這些選項選擇單執行緒或多執行緒執行時例程,指示多執行緒模組是否為 DLL,並選擇執行時庫的釋出版本或除錯版本。 (1)/MD    定義 _MT 和 _DLL 以便同時從標準 .h 檔案中選擇執行時例程的多執行緒特定版本和 DLL特定版本。此選項還使編譯器將庫名 MSVCRT.lib 放入 .obj 檔案中。用此選項編譯的應用程式靜態連結到MSVCRT.lib。該庫提供允許連結器解析外部引用的程式碼層。實際工作程式碼包含在 MSVCR71.DLL 中,該庫必須在執行時對於與MSVCRT.lib 連結的應用程式可用。當在定義了 _STATIC_CPPLIB (/D_STATIC_CPPLIB) 的情況下使用/MD 時,它將導致應用程式通過靜態多執行緒標準 C++ 庫 (libcpmt.lib) 而非動態版本 (msvcprt.lib)進行連結,同時仍通過 msvcrt.lib 動態連結到主 CRT。 (2)/MDd 
   定義 _DEBUG、_MT 和 _DLL,以便從標準 .h檔案中選擇執行時例程的除錯多執行緒特定版本和 DLL 特定版本。它還使編譯器將庫名 MSVCRTD.lib 放入 .obj檔案中。 (3)/ML    使編譯器將庫名 LIBC.lib 放入 .obj 檔案中,以便連結器使用 LIBC.lib解析外部符號。這是編譯器的預設操作。LIBC.lib 不提供多執行緒支援。 (4)/MLd    定義 _DEBUG 並使編譯器將庫名 LIBCD.lib 放入 .obj 檔案中,以便連結器使用LIBCD.lib 解析外部符號。LIBCD.lib 不提供多執行緒支援。 (5)/MT    定義 _MT,以便從標準頭 (.h)檔案中選擇執行時例程的多執行緒特定版本。此選項還使編譯器將庫名 LIBCMT.lib 放入 .obj 檔案中,以便連結器使用LIBCMT.lib 解析外部符號。建立多執行緒程式需要 /MT    或 /MD(或它們的除錯等效選項 /MTd 或 /MDd)。 (6)/MTd    定義_DEBUG 和 _MT。定義 _MT 會導致從標準 .h 檔案中選擇執行時例程的多執行緒特定版本。此選項還使編譯器將庫名LIBCMTD.lib 放入 .obj 檔案中,以便連結器使用 LIBCMTD.lib 解析外部符號。建立多執行緒程式需要 /MTd 或/MDd(或它們的非除錯等效選項 /MT 或 MD)。 (7)/LD    建立 DLL。將 /DLL 選項傳遞到連結器。連結器查詢 DllMain函式,但並不需要該函式。如果沒有編寫 DllMain 函式,連結器將插入返回 TRUE 的 DllMain 函式。連結 DLL啟動程式碼。如果命令列上未指定匯出 (.exp) 檔案,則建立匯入庫 (.lib);將匯入庫連結到呼叫您的 DLL 的應用程式。將/Fe 解釋為命名 DLL 而不是 .exe 檔案;預設程式名成為基名稱.dll 而不是基名稱.exe。如果還未顯式指定 /M選項之一,則將預設執行時庫支援更改為 /MT。 (8)/LDd    建立除錯 DLL。定義 _DEBUG。警告  不要混合使用執行時庫的靜態版本和動態版本。在一個程序中有多個執行時庫副本會導致問題,因為副本中的靜態資料不與其他副本共享。連結器禁止在.exe 檔案內部既使用靜態版本又使用動態版本連結,但您仍可以使用執行時庫的兩個(或更多)副本。例如,當與用動態 (DLL)版本的執行時庫連結的 .exe檔案一起使用時,用靜態(非DLL)版本的執行時庫連結的動態連結庫可能導致問題。(還應該避免在一個程序中混合使用這些庫的除錯版本和非除錯版本)。


No.1 :錯誤 :Libcmtd.lib(wincrt0.obj) : error LNK2019: 無法解析的外部符號 [email protected],該符號在函式 ___tmainCRTStartup 中被引用

解決方法:

專案 --> 屬性 --> 配置屬性 --> 連結器 --> 高階 --> 入口點 :    填寫 wWinMainCRTStartup。

No.2 :錯誤:

1>uafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new(unsigned int)" ([email protected]@Z) 已經在 LIBCMTD.lib(new.obj) 中定義
1>uafxcwd.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete(void *)" ([email protected]@Z) 已經在 LIBCMTD.lib(dbgdel.obj) 中定義
1>uafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new[](unsigned int)" ([email protected]@Z) 已經在 libcpmtd.lib(newaop.obj) 中定義
1>uafxcwd.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete[](void *)" ([email protected]@Z) 已經在 LIBCMTD.lib(delete2.obj) 中定義

解決方法:

專案 --> 屬性 --> 配置屬性 --> 連結器 --> 輸入 --> 附加依賴項 : 加入 

uafxcwd.lib 

Libcmtd.lib

專案 --> 屬性 --> 配置屬性 --> 連結器 --> 輸入 --> 忽略特定預設庫 :加入

uafxcwd.lib 

Libcmtd.lib

No.3:警告:

1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\stdint.h(72): warning C4005: “INT8_MIN”: 巨集重定義
1>          c:\program files (x86)\microsoft sdks\windows\v7.0a\include\intsafe.h(144) : 參見“INT8_MIN”的前一個定義
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\stdint.h(73): warning C4005: “INT16_MIN”: 巨集重定義
1>          c:\program files (x86)\microsoft sdks\windows\v7.0a\include\intsafe.h(146) : 參見“INT16_MIN”的前一個定義
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\stdint.h(74): warning C4005: “INT32_MIN”: 巨集重定義
1>          c:\program files (x86)\microsoft sdks\windows\v7.0a\include\intsafe.h(148) : 參見“INT32_MIN”的前一個定義
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\stdint.h(76): warning C4005: “INT8_MAX”: 巨集重定義

解決方法:

在標頭檔案中加入:

#ifdef _MSC_VER
#pragma warning (push)
#pragma warning (disable : 4005)
#include <intsafe.h>
#include <stdint.h>
#pragma warning (pop)
#endif

No.4:警告:

取消 strcpy strcpy_s 這些警告。

解決方法:

專案 --> 屬性 --> 配置屬性 --> C/C++ --> 前處理器 --> 前處理器定義 :_CRT_SECURE_NO_WARNINGS 

再在標頭檔案中加入

#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS 
#endif

轉載自:
http://blog.sina.com.cn/s/blog_6db64b4a01010pxr.html
http://blog.csdn.net/mkr127/article/details/8555345

相關推薦

vc連結靜態的時候注意的問題

1、VC編譯選項 多執行緒 (/MT) 多執行緒除錯 (/MTd) 多執行緒 DLL  (/MD) 多執行緒除錯 DLL  (/MDd) 2、C執行時庫                     庫檔案 Single thread(static link) ML           libc.lib Deb

【C/C++開發】強制連結靜態所有符號(包括未被使用的)

C++程式在連結一個靜態庫時,如果該靜態庫裡的某些方法沒有任何地方呼叫到,最終這些沒有被呼叫到的方法或變數將會被丟棄掉,不會被連結到目標程式中。這樣做大大減小生成二進位制檔案的體積。但是,某些時候,即使靜態庫裡的某些方法沒有任何地方使用到,我們也希望將這些沒有使用到的程式碼編譯進最終的二進位制檔案中

Linux下動態(.so)和靜態(.a) 的區別 Linux下動態(.so)和靜態(.a) 的區別 動態(.so)連結靜態(.a)的情況總結

Linux下動態庫(.so)和靜態庫(.a) 的區別   靜態庫在程式編譯時會被連線到目的碼中,程式執行時將不再需要該靜態庫。編譯之後程式檔案大,但載入快,隔離性也好。 動態庫在程式編譯時並不會被連線到目的碼中,而是在程式執行是才被載入,因此在程式執行時還需要動態庫存在。多個

關於Cmake 連結靜態出現undefined reference to錯誤

在編寫一個C++專案的時候,使用cmake管理工程,成功連結一個靜態庫,但是在編譯時仍然出現undefined reference to 的錯誤。 最終發現問題是由於c和c++混編導致的。 解決方案: 由於我連結的庫是使用c語言編寫,所以需要在include標頭檔案時加上 #

Qt5.7中使用MySQL Driver(需要把libmysql.dll檔案拷貝到Qt的bin目錄中。或者自己編譯的時候,連結靜態

1、使用環境 Qt5.7的安裝安裝就已經帶了MySQL Driver,只需要在安裝的時候選擇一下即可。 如果沒有安裝,可以採取自己編譯的方式。 在Qt的原始碼包的qtbase\src\sql\drivers\mysql路徑下,就是相關的原始碼檔案。 這裡就不說編譯方式了。只

CURL 連結靜態

一、 編譯屬於你的  CURL 下載最新版本 CURL : curl-7.54.0; 開啟你的 vs 等ide 的命令提示符視窗 編譯成功後: 在../Builds目錄下查詢 你要所需要的lib 庫 二、靜態連結庫使用: 當程式中使用 lib 庫進行編譯時候提

在Linux動態Project中連結靜態時,遇到error adding symbols: Bad value的問題

現象:在生成某個動態庫比如SDS_Utility.so的時候,需要靜態連結某些庫,如libboost_log.a, 報上述錯誤。 原因:靜態庫想連結進動態庫,必須滿足一定的條件,靜態庫需要加-fPIC選項編譯,編譯成Position Independent C

linux 連結 靜態 undefined reference to

最近將專案移植到linux上,工程需要依賴三個靜態庫:libprojcommon.a libluabind.a liblua.a 依賴關係是projcommon依賴luabind,luabind依賴lua,所以專案最終的連結引數是這樣的: -L/home/boy/ProjCommon/lib -lproj

gcc使用---動態連結靜態

       00001f18 a _DYNAMIC        00001ff4 a _GLOBAL_OFFSET_TABLE_w _Jv_RegisterClasses        00001f08 d __CTOR_END__        00001f04 d __CTOR_LIST__    

ubuntu下gcc連結靜態.a檔案

    ubuntu系統下需要連結.a靜態庫檔案,查找了一些資料執行gcc命令發現都不能連結成功。最後自己通過一些測試,成功連結並且執行。     使用命令如下: gcc -o test dll_test.c -L  ./  SDKUseDll.a     說明: test

動態靜態編譯測試:含靜態連結動態靜態,動態連結靜態、動態

本文的目的是測試各種型別庫的編譯後的使用效果,包括庫又連結其他庫的編譯方法,使用方法,依賴性等。 太長不看版:請跳至文章最後的總結對比表。 一。內容包含: ①靜態庫libbb.a依賴靜態庫libaa.a的測試; ②靜態庫libbb.a依賴動態庫libaa.so的測試;

動態(.so)連結靜態(.a)的總結

動態庫(.so)連結靜態庫(.a)的情況總結  一般來說在連結時想要使用靜態庫有三種方法: 1、link時加上 -static 選項;當加上 -static選項後,gcc會把所有用到的庫都做靜態連線。 2、link時直接指定想要靜態連線的.a檔案的絕對路徑。優點是除非.a檔案不存在,否則肯定有效;缺點也是很

Xcode自定義靜態需要注意點 Invalid bitcode signature

當自己辛辛苦苦編寫完一個靜態庫,新增到工程後在debug的環境下編譯正常使用,但是切到release環境下的時候編譯,又會出現以下錯誤: error: Invalid bitcode signature clang: error: linker command failed

淺談GCC/Clang生成和連結靜態/動態

為了方便下面的講解,先寫兩個C++原始檔,程式碼如下: 1 2 3 4 5 //add.cpp int add(int a, int b) { return a + b; } 1 2 3 4 5 6 7 8 9 10 11 //main.cpp #in

VC執行版本不同導致連結.LIB靜態時發生重複定義問題的一個案例分析和總結

from:http://blog.csdn.net/ithzhang/article/details/13170047 Background MSDN中對於在不同的配置下Link的LIB作了說明: C Runtime Library: 開關 對應的庫

靜態連結ffmpeg注意的問題

1. 最近使用ffmpeg靜態庫進行連結,提示 undefined reference,排查發現靜態庫的順序導致的,靜態庫對先後順序有嚴格要求 2. 使用ffmpeg庫時,在連結時,需要加上-lm -

ndk連結本地靜態注意事項

1.連結方法  LOCAL_LDFLAGS:= $(LOCAL_PATH)/lib/$(TARGET_ARCH_ABI)/libadd.a  //本地靜態庫位置 2.連結多個靜態庫時,注意靜態庫的順序。順序不對會出錯。

VC運行版本不同導致鏈接.LIB靜態時發生重復定義問題的一個案例分析和總結

修改 borde 並且 release 鏈接 部分 sdn 托管代碼 兩個 MSDN中對於在不同的配置下Link的LIB作了說明: C Runtime Library: 開關 對應的庫 版本 /MD

VS編譯靜態 .lib 其中Release 版本比Debug版本大好多原因

bug -1 工程 blog 技術分享 其中 logs debug image 如果工程代碼使用了: 把此選項關閉即可減少庫大小不少: VS編譯靜態庫 .lib 其中Release 版本比Debug版本要大好多原因

C/C++靜態連結原理

前面我們學習了編譯連結的一些知識,現在來看看靜態庫連結的一些知識~ 靜態庫本質上就是使用ar命令打包一堆.o檔案: $ ar -r test.a myObj1.o myObj2.o   靜態庫沒有標準,不同的linux下都會有些細微的差別。大致的格式: Glo