一、VC++6.0制作、使用靜態庫
靜態庫制作
1.如圖一在VC++6.0中new一個的為win32 static library工程並新建一個.cpp和一個.h(C++header file)文件
2..cpp程序直接照老師給的打,注意這里需要改錯,去掉(long)
3. .h文件需要自己編寫格式如下。以head.h為例
#ifndef _HEAD_H_
#define _HEAD_H_
unsigned long unsgn_pow(unsigned int,unsigned int);
#endif
4.Build
5.此時會在根目錄debug文件夾中生成一個.lib文件這就是我們要的靜態庫
靜態庫使用
1.New 一個普通空白測試cpp文件(不要建立新的工程不然會報錯)。將測試代碼輸入。測試代碼越簡單越好,至於
老師給的代碼反正我沒看懂。我直接將賦值那段代碼改為自己輸入x,y的值了。
2.在測試代碼中包含(#include "head.h")
3.工程->設置->連接->輸入->對象/庫模塊中添加你所生成的.lib文件。
(遇到無數錯誤,這樣應該能一次作出)下面給出一些錯誤的調試方法。
連接欄中沒有對象/庫模塊 提示找不到lib
可能 需要在tools/options設置正確的引用路徑
二、VC++6.0制作、使用動態庫
動態庫知識普及
一)動態鏈接庫和靜態鏈接庫
靜態鏈接庫:lib中的函數不僅被連接,全部實現都被直接包含在最終生成的EXE文件中,只是實現是不可見的。
動態鏈接庫:dll不必被包含在最終的EXE中,靜態調用時僅把函數名或者變量名或者類名鏈接到EXE文件中,而這些東西的實體都只有在運行時才從動態庫中導入到可執行文件中,動態調用的時候EXE文件執行時可以直接動態地引用和卸載DLL文件。
同時,靜態鏈接庫中不能再包含其他的動態鏈接庫或靜態庫,而動態鏈接庫中可以包含其他的動態或靜態庫。
(二)回顧一下VC++支持的DLL:
DLL的編制與具體的編程語言及編譯器無關,動態鏈接庫隨處可見,VC++支持三種DLL:非MFC動態庫、MFC規則DLL和MFC擴展DLL。DLL導出函數(或變量、類)可供應用程序調用;DLL內部函數只能在DLL程序內使用,應用程序無法調用它們。
(三)導出函數的聲明方式:
一種在函數聲明類型和函數名之間加上“_declspec(dllexport)”。
另外一種采用模塊定義(.def)文件聲明,需要在庫工程中添加模塊文件,格式如下:
LIBRARY 庫工程名稱
EXPORTS 導出函數名
(四)DLL的調用方式:
靜態調用中,由編譯系統完成對DLL的加載和應用程序結束時DLL的卸載。
動態調用中,由編程者用API函數加載和卸載DLL(DLL加載—DLL函數地址獲取—DLL釋放)方式。
動態庫制作
1. VC++6.0中new一個的為win32 Dynamic-Link Library工程,創建.cpp和.h文件。
2.將庫代碼和h文件敲入,這里需要注意要在函數定義時加前綴
extern "C" __declspec(dllexport) //聲明為C編譯、連接方式的外部函數
cpp和h文件均要加入前綴,這樣才能產生lib文件,不然只有dll文件。
3.Bulid
4.在根目錄下的debug文件中就會找到dll和lib文件
(一般的動態庫在創建工程時候會選擇 New--projects--MFC AppWizard(dll)--Regular DLL using shared MFC DLL,這樣會產生標准的def.文件方便再次使用)
動態庫使用(將dll文件和lib文件考入測試工程所在目錄)
1°靜態調用
1. new--projects--win32 console application--an empty project
2. 添加h文件:(test.h) (.h可以寫到.cpp文件中)
#pragma comment(lib,"xxxx.lib") //告訴編譯器DLL相對應的lib文件所在路徑和文件名
extern "C" _declspec(dllimport) int _stdcall Add_new(int a,int b);//聲明導入函數
3. 添加測試cpp文件
2° 動態調用
即采用LoadLibrary()函數對dll文件直接調用,如下列代碼
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>//LoadLibrary所需要的頭文件
typedef int (* Peal)(int ,int);//定義一個名為Peal的與unsgn_pow函數接受參數類型和返回值均相同的函數指針類型
int main()
{
HINSTANCE Linke;//創建名為Linke的句柄
Peal unsgn_pow;//將指針Peal指向函數
Linke=LoadLibrary("dfg123.dll");//動態加載DLL模塊句柄
if(Linke)
{
unsgn_pow=(Peal) GetProcAddress(Linke,"unsgn_pow");//得到所加載DLL模塊中函數的地址
if(unsgn_pow)
{
unsigned int x,y;
unsigned long res;
printf("ple input 2 number(int)\n");
scanf("%d %d",&x,&y);
res =unsgn_pow(x,y);
printf("%u ^ %u=%u\n", x, y, res);
exit(0);
}
FreeLibrary(Linke);//釋放
}
return 0;
}
注意:如果你按照我的測試代碼運行的話結果如下
原代碼運行答案 傳參數為argv[1]=2 argv[2]=3 argv[3]= 4 argv[4]=5