參考來源:https://blog.csdn.net/hanfeidyx/article/details/87972227
環境:visual studio 2017
需要打包的程序可以包含第三方的靜態庫 (.lib)文件,也就是說你可以使用第三方的庫函數開發你的功能,然后打包。
一、設計功能模塊的入口函數
功能模塊的入口函數是指你開發的程序的對外的接口,也就是說生成動態庫后,其他程序通過這個接口函數來使用你開發的功能。
1. 入口函數在聲明時要加上“__declspec(dllexport) ”,表明這是一個入口函數。? 在頭文件中書寫
例如? __declspec(dllexport)? int function (int a, int b);//
可加上命名空間namespace dllPro{
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?__declspec(dllexport)? int function (int a, int b);
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?}
2. 如果你的動態庫要在C#中托管調用,聲明時要加上“extern "C" __declspec(dllexport)”;在C++中調用就不需要了。
例如? extern "C" __declspec(dllexport)? int function (int a, int b);
namespace dllPro{
? ? ? ? ? ? ? ? ? ? ? ? ? ?extern "C" __declspec(dllexport)? int function (int a, int b);
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?}
3. 入口函數的實現,正常就可以。一般聲明在.h文件中,實現在.cpp文件中。當然也可以把聲明和實現寫在一起。
4. 入口函數的返回值和參數類型要設計好,最好使用基礎類型。(方便其他程序調用時,參數的匹配)
如果要在C#中托管,就一定要使用C/C++的基礎類型。
二、生成動態庫(注意配置步驟3,4,5,否則會有各種如報錯為“.dll不是有效win32應用程序”等這類不搭界的錯誤))
1. 在編寫程序的過程中,會有main.cpp文件,在main函數中調用入口函數,調試程序。
2. 但是生成動態庫時,需要將整個main.cpp都注釋,因為編譯生成的庫不需要main函數入口,只是要在其他程序中調用入口函數,實現功能。
3. 在visual studio中,右鍵工程,選擇“屬性”,在“屬性頁”中,選擇“配置屬性”中的“常規”,然后在右界面中的“項目默認值”中,重新選擇“配置類型”,選擇“動態庫(dll)”選項。
4. 因為整個main.cpp都被注釋了,所以程序沒有入口函數,這時候直接生成,會因為沒有主函數(main)而報錯。所以仍然在在“屬性頁”中,選擇“配置屬性”中的“鏈接器”下的“系統”選項,然后在右界面中重新選擇“子系統”為“窗口 (/SUBSYSTEM:WINDOWS)”,這樣生成就不會報錯了。
5. 在visual studio中選擇“生成”,然后“生成解決方案”,要注意選擇相應的版本,Debug或者Release版本。最后就可以在工程目錄下的Debug或者Release目錄下找到對應的 .lib 和 .dll 文件,名字與工程名字相同。
6. 如果在你的工程中使用了第三方庫函數,就需要注意一下。
? ? 如果使用的是第三方的.lib 靜態庫,就不用管了,你編譯生成的dll會包含該文件;
? ? 如果使用了其他第三方的動態庫dll文件,那么在調用你自己編譯的動態庫時,還需要這些第三方的動態庫。
7. 要使用你編譯的動態庫,一共要用到三種文件
? ? 頭文件,也就是 .h 后綴的文件,包括你工程中自己寫的所有.h文件,和第三方庫的所有.h 文件,可以放在一個文件夾中,例如“include”,自己可以命名。
? ? 靜態庫文件,也就是 .lib 文件,就是你在步驟5中生成的那個lib文件,只有一個,可以放在一個文件夾中例如“lib”, 也可以放在你將要使用這個庫的工程的目錄下。
? ? 動態庫文件,也就是 .dll 文件,就是你在步驟5中生成的那個dll文件,和其他你用到的第三方的dll文件,這些dll文件需要放在你將要使用這個庫的工程的目錄下。
三、使用自己編譯的動態庫
1. 新建工程項目,添加main.cpp項。
? ? 拷貝步驟二第7項中的 “include”目錄、lib目錄或者lib文件(沒有目錄)、所有動態庫dll文件到新建的工程目錄下,也就是和.vcxproj文件同一目錄下,不是解決方案目錄。
? ? 在新建工程項目的“屬性頁”中選擇“配置屬性”中的“VC++目錄”,在右界面中填寫“包含目錄”,輸入 include (和步驟二第7項中頭文件目錄的目錄名相同就可以,因為已經拷貝到工程目錄下,所以使用相對路徑就可以);填寫“庫目錄”,輸入 lib(和步驟二第7項中靜態庫目錄的目錄名相同就可以,因為已經拷貝到工程目錄下,所以使用相對路徑就可以),如果沒有靜態庫目錄,也可以不寫。
? ? 在新建工程項目的“屬性頁”中選擇“配置屬性”中的“鏈接器”,選擇“輸入”,在右界面中的“附加依賴項”中填寫靜態庫名稱,例如 xxx.lib (步驟二第7項中的lib文件名)(編譯器會在你的“庫目錄”(如上圖所示)中查找該文件并加載,如果沒有庫目錄,會在工程目錄下查找該文件并加載)
? ? 動態庫拷貝到新建工程目錄下就可以了,不用配置,編譯器會自動找到。
2. 在main.cpp中包含你的入口函數所在的頭文件,因為已經設置了“包含目錄”,所以可以直接找到該頭文件。
? ? 然后在main函數中調用該入口函數,要注意函數的參數要匹配。
? ? 就可以使用該函數了。
3. 編譯自己的動態庫,可以作為一個功能模塊,方便別人調用。
? ? 還可以打包一些第三方的庫函數,在新的工程中直接使用編譯好的自己的庫函數,不用再去為新建工程配置第三方庫了。