VS2008 建立DLL和調用DLL

隱式連接就是在程序開始執行時就將DLL文件加載到應用程序當中。隱式連接必須的文件:lib .


顯式連接是應用程序在執行過程當中隨時能夠加載DLL文件,也能夠隨時卸載DLL文件,這是隱式連接所沒法做到的,因此顯式連接具備更好的靈活性,對於解釋性語言更爲合適。不過實現顯式連接要麻煩一些。在應用程序中用LoadLibrary或MFC提供的AfxLoadLibrary顯式的將本身所作的動態連接庫調進來,動態連接庫的文件名便是上述兩個函數的參數,此後再用GetProcAddress()獲取想要引入的函數。自此,你就能夠象使用如同在應用程序自定義的函數同樣來調用此引入函數了。在應用程序退出以前,應該用FreeLibrary或MFC提供的AfxFreeLibrary釋放動態連接庫。


使用顯式連接應用程序編譯時不須要使用相應的Lib文件。另外,使用GetProcAddress()函數時,能夠利用MAKEINTRESOURCE()函數直接使用DLL中函數出現的順序號,如將GetProcAddress(hDLL,"Min")改成GetProcAddress(hDLL, MAKEINTRESOURCE(2))(函數Min()在DLL中的順序號是2),這樣調用DLL中的函數速度很快,可是要記住函數的使用序號,不然會發生錯誤。 


顯式連接必須的文件:dll .


1、DLL的建立 (用.def文件建立動態鏈接庫)
建立項目->Win32->Win32項目,名稱:MyDLL->選擇DLL
一、新建頭文件testdll.h
testdll.h代碼以下:
#ifndef TestDll_H_
#define TestDll_H_
#ifdef MYLIBDLL
#define MYLIBDLL extern "C" _declspec(dllimport) 
#else
#define MYLIBDLL extern "C" _declspec(dllexport) 
#endif
MYLIBDLL int Add(int plus1, int plus2);
//You can also write like this:
//extern "C" {
//_declspec(dllexport) int Add(int plus1, int plus2);
//};
#endif

二、新建源文件testdll.cpp
testdll.cpp代碼以下:
#include "stdafx.h"
#include "testdll.h"
#include <iostream>
using namespace std;
int Add(int plus1, int plus2)
{
int add_result = plus1 + plus2;
return add_result;
}

三、新建模塊定義文件mydll.def
mydll.def代碼以下:
LIBRARY "MyDLL"
EXPORTS
Add @1

四、vs2008自動建立dllmain.cpp文件,它 定義了DLL 應用程序的入口點。

dllmain.cpp代碼以下: ios

// dllmain.cpp : 定義 DLL 應用程序的入口點。
#include "stdafx.h"
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
      )
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
  break;
}
return TRUE;
}
最後,編譯生成MyDLL.dll文件和MyDLL.lib文件。
2、DLL的使用(靜態連接、隱式連接  )
建立項目->Win32控制檯應用程序,名稱:UseDLL。
將MyDLL.lib文件放在與UseDLL.exe文件的目錄下。
建立源文件UseDll.cpp
UseDll.cpp代碼以下:
// UseDll.cpp : 定義控制檯應用程序的入口點。
//
#pragma comment (lib,"MyDLL.lib")
#include "stdafx.h"
#include <iostream>
using namespace std;
extern "C" _declspec(dllimport) int Add(int plus1, int plus2);   //或者直接在工程的Setting->Link頁中設置導入MyDll.lib既可
int _tmain(int argc, _TCHAR* argv[])
{
int a = 20;
int b = 30;
cout<<"a+b="<<Add(a, b)<<endl;
getchar();
return 0;
}

運行結果以下:
a+b=50
3、DLL的使用(動態調用、顯式連接)
建立項目->Win32控制檯應用程序,名稱:UseDLL。
將MyDLL.dll文件放在與UseDLL.exe文件的目錄下。
建立源文件UseDll.cpp
UseDll.cpp代碼以下: 

// UseDll.cpp : 定義控制檯應用程序的入口點。
//
#include "stdafx.h"
#include <iostream>
#include <windows.h>
using namespace std;
typedef int (*AddFunc)(int a,int b);
int _tmain(int argc, _TCHAR* argv[])
{
	HINSTANCE hInstLibrary = LoadLibrary(_T("MyDLL.dll"));//注意此處必須有_T()函數。
	if (hInstLibrary == NULL)     
	{     
		FreeLibrary(hInstLibrary);  
		cout<<"LoadLibrary error!"<<endl;
		getchar();
		return 0;
	} 
	AddFunc _AddFunc = (AddFunc)GetProcAddress(hInstLibrary, "Add");
	if (_AddFunc == NULL) 
	{       
		FreeLibrary(hInstLibrary);  
		cout<<"GetProcAddress error!"<<endl;
		getchar();
		return 0;
	}
	cout <<"a+b="<<_AddFunc(20, 30) << endl;    
	getchar();
	FreeLibrary(hInstLibrary);
	return 0;
}

Cyper的筆記,第二步靜態連接報以下錯誤 windows

1>------ Build started: Project: testdll, Configuration: Debug Win32 ------
1>Linking...
1>testdll.obj : error LNK2019: unresolved external symbol __imp__Add referenced in function _wmain
1>C:\f\vsProject\Vc9.0\testdll\Debug\testdll.exe : fatal error LNK1120: 1 unresolved externals
1>Build log was saved at "file://c:\f\vsProject\Vc9.0\testdll\testdll\Debug\BuildLog.htm"
1>testdll - 2 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

解決: 函數

// UseDll.cpp : 定義控制檯應用程序的入口點。
//
#include "stdafx.h"
#include <iostream>
using namespace std;
#pragma comment (lib,"MyDLL.lib")
extern "C" _declspec(dllimport) int Add(int plus1, int plus2);   //或者直接在工程的Setting->Link頁中設置導入MyDll.lib既可
int _tmain(int argc, _TCHAR* argv[])
{
	int a = 20;
	int b = 30;
	cout<<"a+b="<<Add(a, b)<<endl;
	getchar();
	return 0;
}
把#prama這一行移到stdafx.h下面就沒有錯了(折騰了好久才試出來
相關文章
相關標籤/搜索