當前位置:首頁 » 編程軟體 » 編譯鏈接同名依賴庫

編譯鏈接同名依賴庫

發布時間: 2023-05-29 12:26:46

⑴ 在QTCreate如何添加LIB依賴庫進行編譯

依照上述的格式,你就可以添加編譯時需要的依賴庫了。
這是一種正確的方法,不過在筆者還不知道這種方法的時候,筆者時通過修改Makefile的。在debug目錄下,有一個Makefile文件,你可以通過在如下的方式:在Makefile裡面找到
在這里進行添加。不過這種方式的有一個問題:那就是當.pro的文件變化的時候,Makefile就會被重新組織和生成,這個時候LIBS 就會被改變,你需要再次添加,不然又會編譯出錯。希望這個方法對大家有用!

⑵ 我編譯A靜態庫的時候依賴了B靜態庫,我編譯的程序依賴A靜態庫和B靜態庫,這樣B靜態庫是不是會有重復的部分

靜態庫在程序的鏈接階段被復制到了程序中。
你用依賴這個詞。
程序編譯一般需經預處理、編譯、匯編和鏈接幾個步驟。
在鏈接步驟中,靜態庫才會被復制。
因為靜態庫在程序的鏈接階段被復制到了程序中,和程序運行的時候沒有關系。
存在幾個鏈接?
那麼就幾分拷貝。

⑶ Linux動態庫多重依賴,編譯問題!!!!!!

這只能說明一個問題,你依賴的庫本隱基銷身有問題,沒有把它的依鋒檔賴都加進去,也就是你例子中的①灶游libb.so依賴liba.so;,你應該在生成libb.so的時候,把對liba.so的依賴加進去,這樣應該就沒有問題了。

⑷ c腳本在不同系統中編譯和鏈接依賴的庫文件有何區別

問題1,
區別很大,跨OS編譯的區別就在於OS的本質區別,有一下幾點:
a, 位元組排序,一個int型的數據在windows里是由高地址存到低地址的4個位元組的(假設是32位機器),但是在某些UNIX伺服器,如AIX,它的排序方式就相反的,所以當程序被編譯成低級語言(例如匯編)的時候,內存及CPU的處理就會截然相反
b, 字長,有些unix伺服器是64位的,但大多WINDOWS是32位,那麼定義一個整形的時候就有用8個位元組和4個位元組的區別,字長不一樣,那麼執行起來用對內存的使用也自然就不一樣咯。
c,所謂的庫,也是由編譯器編譯出來的,在不同的OS下,由同一個代碼編譯出來的庫也會不一樣。
d,編譯器也各不相同,也會導致編譯出程序不完全相同。
e,所謂的調用,也就是將程序和庫一起打包,然後在找到庫裡面所定義的函數罷了

綜上,當一個程序或者庫要從其他OS搬到另一個不同規格的OS上的時候,一定要重新編譯一下草能確保程序跑起來不發生錯誤,求其原因也就是因為OS的本質區別,兼容的話,其實就是看OS是否在規格上有沒有本質區別

二,庫文件的編譯是單向的,所以無法取回源碼
.a庫的打包例: ar r libabc.a a.o b.o c.o
將a.o b.o c.o 合並打包成libabc.a。注意哦(.a一定要以lib開始.a結束哦)
WIN下我不是很在行,你說的lib大包應該沒錯。

三,我不是很清楚

希望對你有幫助,我2年工作的精華

⑸ AIX系統下,採用xlC_r編譯、鏈接多個動態庫,不同的動態庫有同名的類,導致程序異常退出,如何解決

用域操作來區分同名類, 使用的時候指明域名就可以了

比如這樣: 你把其中一個同名類用域名來操作,另一個用全局域操作,當然,你也可以都採用命名空間來處理.

m.cpp:#include <stdio.h>
m.cpp:namespace james
m.cpp:{
m.cpp: #include "james.h"
m.cpp:}
m.cpp:class AA
m.cpp:{
m.cpp:public:
m.cpp: AA() { printf("A() %s\n", __FILE__); }
m.cpp: ~AA() { printf("~A()\n"); }
m.cpp:};
m.cpp://using namespace james; // 這句如果放開就會命名沖突, 你可以試試,如果要方便使用,就是兩個類用兩個不同的命名空間,然後在某個文件中如果僅僅用到其中一個,那麼你可以用using 關鍵字指定其中一個, 就和你原來的使用一樣了.
m.cpp:int main()
m.cpp:{
m.cpp: james::AA o;
m.cpp: AA o2;
m.cpp:}
james.h:#include <stdio.h>
james.h:
james.h:class AA
james.h:{
james.h:public:
james.h: AA() { printf("A() %s\n", __FILE__); }
james.h: ~AA() { printf("~A()\n"); }
james.h:};
Makefile:
Makefile:all: m.cpp james.h
Makefile: g++ $^

⑹ OpenCV靜態庫編譯與鏈接

以OpenCV-4.0.0為例說明在Ubuntu環境下的靜態庫編譯與鏈接方法:

opencv依賴第三方的庫,所以當把opencv編譯成靜態庫的時候,注意要把它運行時必要的依賴庫也編譯進來,opencv源碼內有自己的3rdparty,主要有:libjpeg、libpng、libtiff、libzlib、libwebp、libprotobuf、ffmpeg(用到video時編譯)、libgtk(用於顯示界面顯示,伺服器部署不會用到),可以通過cmake -LA來查看配置的編譯信息,再根據信息考慮把opencv的哪些mole編譯進來。

鏈接時指定opencv的靜態庫以及依賴的庫。另外需要注意頭文件的問題,通過CMakeLists把opencv加入項目編譯時,由於opencv編譯完成後要install才會把所用的頭文件集中拷貝到一個地方,所以事先將頭文件拷貝到了項目的opencv目錄下。

⑺ C#代碼編譯動態鏈接庫(DLL)

1.visual studio 新建-項目-類庫

2.一定要選.NET FrameWork

4.配置名字芹簡路徑

或者引用-添加引用

windows路徑:桐知
C:\Program Files\Unity\Hub\Editor<version-number>\Editor\Data\Managed\UnityEngine
macOS路局首消徑:
/Applications/Unity/Hub/Editor/<version-number>/Unity.app/Contents/Managed/UnityEngine

10.添加引用完成後【生成】/【重新生成】

11.生成後的文件在剛才選的路徑/默認路徑

⑻ g++ 編譯命令中依賴的動態庫如果還依賴別的庫,命令怎麼設置

第一步,我先從簡單的調用出發,定義了一個簡單的函數,該函數僅僅實現一個整數加法求和:

LIBEXPORT_API int mySum(int a,int b){ return a+b;}
C# 導入定義:

public class RefComm
{
[DllImport("LibEncrypt.dll",
EntryPoint=" mySum ",
CharSet=CharSet.Auto,CallingConvention=CallingConvention.StdCall)]
public static extern int mySum (int a,int b);
}
在C#中調用測試:

int iSum = RefComm.mySum(,);

運行查看結果iSum為5,調用正確。第一步試驗完成,說明在C#中能夠調用自定義的動態鏈接庫函數。

第二步,我定義了字元串操作的函數(簡單起見,還是採用前面的函數名),返回結果為字元串:

LIBEXPORT_API char *mySum(char *a,char *b){sprintf(b,"%s",a); return a;}
C# 導入定義:

public class RefComm
{
[DllImport("LibEncrypt.dll",
EntryPoint=" mySum ",
CharSet=CharSet.Auto,
CallingConvention=CallingConvention.StdCall)]
public static extern string mySum (string a, string b);
}
在C#中調用測試:

string strDest="";
string strTmp= RefComm.mySum("45", strDest);

運行查看結果 strTmp 為"45",但是strDest為空。我修改動態鏈接庫實現,返回結果為串b:

LIBEXPORT_API char *mySum(char *a,char *b){sprintf(b,"%s",a) return b;}
修改 C# 導入定義,將串b修改為ref方式:

public class RefComm
{
[DllImport("LibEncrypt.dll",
EntryPoint=" mySum ",
CharSet=CharSet.Auto,CallingConvention=CallingConvention.StdCall)]
public static extern string mySum (string a, ref string b);
}
在C#中再調用測試:

string strDest="";
string strTmp= RefComm.mySum("45", ref strDest);
運行查看結果 strTmp 和 strDest 均不對,含不可見字元。再修改 C# 導入定義,將CharSet從Auto修改為Ansi:

public class RefComm
{
[DllImport("LibEncrypt.dll",
EntryPoint=" mySum ",
CharSet=CharSet.Ansi,CallingConvention=CallingConvention.StdCall)]
public static extern string mySum (string a, string b);
}
在C#中再調用測試:

string strDest="";
string strTmp= RefComm. mySum("45", ref strDest);
運行查看結果 strTmp 為"45",但是串 strDest 沒有賦值。第二步實現函數返回串,但是在函數出口參數中沒能進行輸出。再次修改 C# 導入定義,將串b修改為引用(ref):

public class RefComm
{
[DllImport("LibEncrypt.dll",
EntryPoint=" mySum ",
CharSet=CharSet.Ansi,CallingConvention=CallingConvention.StdCall)]
public static extern string mySum (string a, ref string b);
}

運行時調用失敗,不能繼續執行。

第三步,修改動態鏈接庫實現,將b修改為雙重指針:

LIBEXPORT_API char *mySum(char *a,char **b){sprintf((*b),"%s",a); return *b;}
C#導入定義:

public class RefComm
{
[DllImport("LibEncrypt.dll",
EntryPoint=" mySum ",
CharSet=CharSet.Ansi,CallingConvention=CallingConvention.StdCall)]
public static extern string mySum (string a, ref string b);
}
在C#中調用測試:

string strDest="";
string strTmp= RefComm. mySum("45", ref strDest);

運行查看結果 strTmp 和 strDest 均為"45",調用正確。第三步實現了函數出口參數正確輸出結果。

第四步,修改動態鏈接庫實現,實現整數參數的輸出:

LIBEXPORT_API int mySum(int a,int b,int *c){ *c=a+b; return *c;}
C#導入的定義:

public class RefComm
{
[DllImport("LibEncrypt.dll",
EntryPoint=" mySum ",
CharSet=CharSet.Ansi,CallingConvention=CallingConvention.StdCall)]
public static extern int mySum (int a, int b,ref int c);
}
在C#中調用測試:

int c=0;
int iSum= RefComm. mySum(,, ref c);

運行查看結果iSum 和c均為5,調用正確。

經過以上幾個步驟的試驗,基本掌握了如何定義動態庫函數以及如何在 C# 定義導入,有此基礎,很快我實現了變長加密函數在 C# 中的調用,至此目標實現。

三、結論

在 C# 中調用 C++ 編寫的動態鏈接庫函數,如果需要出口參數輸出,則需要使用指針,對於字元串,則需要使用雙重指針,對於 C# 的導入定義,則需要使用引用(ref)定義。

對於函數返回值,C# 導入定義和 C++ 動態庫函數聲明定義需要保持一致,否則會出現函數調用失敗。定義導入時,一定注意 CharSet 和 CallingConvention 參數,否則導致調用失敗或結果異常。運行時,動態鏈接庫放在 C# 程序的目錄下即可,我這里是一個 C# 的動態鏈接庫,兩個動態鏈接庫就在同一個目錄下運行。

⑼ c++動態鏈接庫可不可以有兩個同名函數,靜態鏈接庫呢,可以有兩個同名函數嗎

單個動態庫可以有帆兄弊兩個同名函數,但是不能同時導出來,不然會出錯,不同動態庫可以有同名函數,運行時載入不會有問題態族,塵嘩編譯時指定會有想不到的運行結果。
單個靜態庫可以有同名函數,但是某些編譯器不支持,不同靜態庫之間也可以有同名函數,但如果函數簽名也一致,使用的時候會編譯錯。

⑽ C++編譯鏈接錯誤

C++常見編譯/鏈接錯誤及其解決辦法

1. 解決error LNK2005: ___crtExitProcess 已經在 LIBCMTD.lib(crt0dat.obj) 中定義
有的時候, 在 Debug 模式下編譯沒問題, 換到 Release 模式就發生一堆問題.
典型的例子, 就是因為 c++ runtime library 設定不同, 所造成的重復定義連結錯誤.
而另一個常見的例子是 專案與 library 使用不同的字元集合設定
(如: 一個用 Unicode Character Set, 另一個用 Multi-Byte Character Set)
這個錯誤發生原因, 有可能是
1. 你 link 的 lib 使用 C++ Multi-threaded DLL (/MD)
2. 而你的 source 使用的 C++ runtime library 是 Multi-threaded (/MT)
導致重復定義
解決方法:
兩個使用相同的 C++ runtime library.例如都使用 static 的 Multi-threaded (/MT).
2. 錯誤 1error LNK2005: "private: __thiscall type_info::type_info(class type_info const &)" (??0type_info@@AAE@ABV0@@Z) 已經在 LIBCMT.lib(typinfo.obj) 中定義 MSVCRTD.lib
項目 -> 屬性 -> c/C++ -> 代碼生成 -> 運行時庫 設置為: 多線程調試 DLL (/MDd)
被引用的庫和調用的程序編譯選項不同,需要改成一致後編譯
3.#pragma once與 #ifndef的區別
為了避免同一個文件被include多次
1 #ifndef方式
2 #pragma once方式
在能夠支持這兩種方式的編譯器上,二者並沒有太大的區別,但是兩者仍然還是有一些細微的區別。
方式一:
#ifndef __SOMEFILE_H__
#define __SOMEFILE_H__
... ... // 一些聲明語句
#endif
方式二:
#pragma once
... ... // 一些聲明語句
#ifndef的方式依賴於宏名字不能沖突,這不光可以保證同一個文件不會被包含多次,也能保證內容完全相同的兩個文件不會被不小心同時包含。當然,缺點就是如果不同頭文件的宏名不小心「撞車」,可能就會導致頭文件明明存在,編譯器卻硬說找不到聲明的狀況
#pragma once則由編譯器提供保證:同一個文件不會被包含多次。注意這里所說的「同一個文件」是指物理上的一個文件,而不是指內容相同的兩個文件。帶來的好處是,你不必再費勁想個宏名了,當然也就不會出現宏名碰撞引發的奇怪問題。對應的缺點就是如果某個頭文件有多份拷貝,本方法不能保證他們不被重復包含。當然,相比宏名碰撞引發的「找不到聲明」的問題,重復包含更容易被發現並修正。
方式一由語言支持所以移植性好,方式二 可以避免名字沖突
4.error LNK2019: 無法解析的外部符號 __imp__PathCombineW
PathCombine是Shell api 需要引入庫#pragma comment( lib, "shlwapi.lib")
5.error C2662: "MyClass::GetName()」: 不能將「this」指針從「const MyClass」轉換為「MyClass &」
bool MyClass::operator==(const MyClass* n1) const
{return GetName() == n1->GetName();}
原因是不能在const函數中調用對象的非const方法,MyClass中的GetName()必須是const的。
6.template 模板
模板聲明和定義必須在同一個文件中,而且只有實例話模板類型時才編譯模板實例
7.error C2275: 「MyClass」: 將此類型用作表達式非法 MyClass.Instance();
原因:Instance是靜態方法,用.引用會出錯。應該是MyClass::Instance()
8.error LNK2019: 無法解析的外部符號 "public: __thiscall MyClass(void)
原因:只聲明了構造函數,MyClass(); ,但未定義。 可以定義空函數,或者直接注釋掉,使用默認構造函數。
9.error C2504: 「testing」: 未定義基類
class PackToolTest : testing.Test {}
原因:Test是testing命名空間下的一個類,需要用域操作符,testing::Test
還有一個問題,缺少基類繼承許可權(public、protected、private)
10.error C2864: 「MyClass::_nullpack」: 只有靜態常量整型數據成員才可以在類中初始化
class MyClass {string _nullpack = "test";}
原因:c++ 中,成員變數不能在聲明時初始化,而是在構造函數初始化列表中先初始化
11.error LNK2019: 無法解析的外部符號_WinMain@16int main()
原因:由於創建的是Win32 Project,和Win32 console Project的鏈接庫不同
方法1:在程序最開始的地方加上以下語句
#pragma comment(linker, "/subsystem:console ")
方法2:project > > setting > > 在link 的project options 中將/subsystem:windows(console)刪了
12.類似「已經在 msvcprtd.lib(MSVCP80D.dll) 中定義」問題
vs2005 Debug /Release需要分別配製
分析一下錯誤來源,會發現:
1. 錯誤來源主要是重復定義的問題,而且重復定義的基本上都是VC Runtime和Standard C++ Library中的函數
2. LIBCMT和LIBCPMT為Release下的Lib,本來不應該出現在Debug版本的鏈接的Lib中
3. 重復定義的問題主要出現在:LIBCMT, LIBCPMT, MSVCPRTD, MSVCRTD
來看看出問題的LIB是那些:
1. LIBCMT:C Runtime庫的多線程靜態鏈接的Release版本
2. LIBCPMT:C++ Standard Library的多線程靜態鏈接的Release版本
3. MSVCPRTD:C++ Standard Library的多線程DLL的Debug版本
4. MSVCRTD:C Runtime Library的多線程DLL的Debug版本
當 前我們的配置是多線程DLL的Debug版,因此3和4是應該出現在link的列表中的,不屬於多餘。而後兩者則是只是當多線程靜態鏈接Release版 中才會出現。這提示我在項目中加入的ANTLR.LIB可能是造成這個問題的根源,因為靜態庫的編譯選項很容易和主程序發生沖突,並且根據實際信息我們可 以看出ANTLR.LIB應該是用多線程靜態鏈接的Release版本來編譯的。
解決方法:
1、首先查看編譯項目依賴的其他項目的運行時庫是否一致
2、如果不一致,改為同樣的運行時庫,如在下編譯的是:「多線程調試 DLL (/MDd)」,現在需要把所有的依賴項目的運行時庫都改為一致的庫,就OK了。
13.error C2143: 語法錯誤 : 缺少「;」(在「*」的前面)
原因:產生錯誤處,某類型未include,可能頭文件名拼寫錯誤、頭文件名已更改
14.error C2572: 「MyClass::Invoke」: 重定義默認參數 : 參數 2
string MyClass::Invoke(const CParam& paraObj, INVOKETYPE type = ASYN)
原因:默認參數,只需在聲明時指定。方法定義的時候無需指定默認參數。
string MyClass::Invoke(const CParam& paraObj, INVOKETYPE type )
{ ... }
15.錯誤 C2558 沒有可用的復制構造函數或復制構造函數聲明為「explicit」
試圖復制其復制構造函數為 private 的類。在大多數情況下,不應復制具有 private 復制構造函數的類。通用編程技術聲明 private 復制構造函數以防止直接使用類。該類本身可能無用,或需要另一個類才能正常工作。
嘗試復制其復制構造函數為 explicit 的類。用 explicit 聲明復制構造函數會阻止將類的對象傳遞到函數或從函數返回類的對象。
原因: 拷貝構造函數、賦值函數參數必須用const修飾
16.不能創建抽象類對象
原因: 1. 存在虛函數未實現; 2. 由於疏忽重載虛函數格式錯誤(此問題需要仔細檢查才能發現); 3. 虛函數名稱與系統中已有的虛函數重名,導致重載失敗(這點很納悶)。
17.沒有找到MSCRV80D.dll
工程屬性: 配置類型 由 exe 改成 lib 後生成, 然後再改回來,運行時會出現 「沒有找到MSCRV80D.dll」 的異常
解決方法:
工程屬性:MFC的使用 由 「使用標准Windows庫」 改成 「在靜態庫中使用MFC「 生成 ,然後再改回來,生成、運行 OK
18.CVTRES : fatal error CVT1100: 重復的資源。type:MANIFEST, name:1, language:0x0409
另一個則提示為:
LINK : fatal error LNK1123: 轉換到 COFF 期間失敗: 文件無效或損壞
已經到了鏈接期,應該說,問題就不像編譯通不過那麼別扭了,而查閱MSDN關於這兩個問題的說明,終於找到了解決的方法,現簡單的陳述如下:
首先,出現這兩個問題的原因都是一個,即文件中的現有資源文件和新資源字元串表 ID 沖突。微軟也給出了解決這個問題的方法,但是,在現有的情況下,這個方法是靠不住的,因為,不可能不使用wx.rc資源。所以,一個變通的解決方法就是:
工程屬性->配置屬性-> 清單工具->輸入和輸出->嵌入清單,選擇[否],即可。

熱點內容
安卓手機如何無密碼解鎖vivo 發布:2025-02-13 15:52:10 瀏覽:884
電信50m上傳 發布:2025-02-13 15:47:56 瀏覽:363
清理outlook2010緩存 發布:2025-02-13 15:43:30 瀏覽:54
ohem演算法 發布:2025-02-13 15:40:10 瀏覽:930
java編程課程 發布:2025-02-13 15:36:08 瀏覽:476
cs編譯 發布:2025-02-13 15:36:07 瀏覽:56
高級語言都要編譯解析型語言 發布:2025-02-13 15:06:32 瀏覽:305
openwrt源碼下載 發布:2025-02-13 15:01:59 瀏覽:644
linux刪除一個目錄 發布:2025-02-13 15:00:29 瀏覽:539
螞蟻存儲 發布:2025-02-13 15:00:25 瀏覽:919