VS2008 创建DLL和调用DLL

扶醉桌前 提交于 2019-12-03 19:06:50
隐式链接就是在程序开始执行时就将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 .


一、DLL的创建 (用.def文件创建动态连接库)
创建项目->Win32->Win32项目,名称:MyDLL->选择DLL
1、新建头文件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

2、新建源文件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;
}

3、新建模块定义文件mydll.def
mydll.def代码如下:
LIBRARY "MyDLL"
EXPORTS
Add @1

4、vs2008自动创建dllmain.cpp文件,它 定义了DLL 应用程序的入口点。

dllmain.cpp代码如下:

// 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文件。
二、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
三、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的笔记,第二步静态链接报如下错误

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下面就没有错了(折腾了很久才试出来
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!