1、函数库:把函数组织起来,供程序调用,函数的复用。静态库与动态库。
动态库、静态库是其他语言中也都有对应概念的东西,也是一通百通的。C#中的
Assembly、Java 中的jar 等。
静态库:编译时代码编译进exe 中,会使得程序体积非常庞大。不利于模块的共
享,比如ODBC 的库如果是以静态库的方式的话计算机里访问数据库的程序都会
连接进去ODBC 的代码,也许你的Windows 就不止2、3GB 那么大了,可能20GB
都不止。优点:不会有dll hell 的问题。好像“企业间的吞并”
动态库:dll。代码在dll 中,其他程序调用dll 中的代码,多个程序可以共享。缺
点:dll hell(dll 地狱),版本问题。好像“企业间的合作”。哪怕不需要被其他程序
共享,仍然可以通过dll 的方式减小单个exe 的尺寸,并且有利于开发人员的分
工。
2、编写dll。新建Win32 dynamic link library
只有在函数前标注:extern "C" _declspec(dllexport) 的函数才能被其他的程序
通过dll 的方式调用
extern "C" _declspec(dllexport) int add(int i1,int i2)
{
return i1+i2;
}
(1) 静态链接:新建win32 DialogBased application。把dll 和lib 拷贝到工程目
录下:
声明:
#pragma comment(lib, "dll1.lib")
extern "C" _declspec(dllexport) int add(int i1,int i2);
然后就可以像调用普通函数一样调用了。
如果dll 中函数很多的话,一般都是由dll 开发者开发好.h 文件,把函数的声明都
写好,然后供其他人调用,只要include 就好了。
(2) 动态链接:
//有__cdecl __stdcall 等不同的调用约定,也就是参数的压栈顺序等,暂时不用关
心,只要保证调用的时候和dll 中的调用约定一样就可以。
//否则会报错:The value of ESP was not properly saved across a function call. This is
usually a result of calling a function declared with one calling convention with a
function pointer declared with a different calling convention.
//声明
typedef int(__cdecl* FunctionAdd)(int,int);
函数指针
HMODULE hModule;
FunctionAdd add;
hModule = LoadLibrary("dll1.dll");//调试时hModule 为0x10000000
If(NULL==hModule )
{
//error.
}
add =(FunctionAdd)GetProcAddress(hModule,"add");
If(NULL==add)
{
//error
}
int r = add(1,1);
TCHAR str[256];
wsprintf(str,"1+1=%d",r);
MessageBox(hwnd,str,TEXT("提示"),MB_OK);
FreeLibrary(hModule);
2、其他语言也有对应的概念,C#、Java 中的反射。
静态链接和动态链接的区别:静态链接在程序启动的时候就会去检查dll 是否存
在,如果不存在在启动的时候就会报错,程序无法启动;动态链接是在运行到的
时候才会去检查是否存在,而且可以由程序员决定在dll 不存在的时候判断逻辑。
例子:
动态链接库的建立
vc++ 6.0
新建一个简单的Win32 Dynamic-Link Library 名字为:动态链接库
#include "stdafx.h"
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
extern "C" _declspec(dllexport) int add(int i1,int i2)
{
return i1+i2;
}
组建,生成 动态链接库.dll和动态链接库.lib
静态链接方法:
vc++ 6.0 新建一个Win32 DialogBased Application 名字为dll静态链接
把 动态链接库.dll和动态链接库.lib两个文件 复制在工程的根目录下
#include "stdafx.h"
#include <windows.h>
#include <windowsx.h>
#include "resource.h"
#include "MainDlg.h"
#pragma comment(lib, "动态链接库.lib")
extern "C" _declspec(dllexport) int add(int i1,int i2);
/*
Template designed by RuPeng.com. Please visit http://www.rupeng.com for more information
如鹏网(http://www.rupeng.com)大学生计算机学习社区,提供大量免费视频学习教程,提供个性化一对一学习指导
*/
BOOL WINAPI Main_Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
HANDLE_MSG(hWnd, WM_INITDIALOG, Main_OnInitDialog);
HANDLE_MSG(hWnd, WM_COMMAND, Main_OnCommand);
HANDLE_MSG(hWnd,WM_CLOSE, Main_OnClose);
}
return FALSE;
}
BOOL Main_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam)
{
return TRUE;
}
void Main_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
switch(id)
{
case IDC_OK:
{
// MessageBox(hwnd,TEXT("欢迎访问如鹏网 www.RuPeng.com 大学生计算机学习社区"),TEXT("问好"),MB_OK);
int num=add(1,2);
TCHAR str[256];
itoa(num,str,10);
MessageBox(hwnd,str,TEXT("提示"),MB_OK);
}
break;
default:
break;
}
}
void Main_OnClose(HWND hwnd)
{
EndDialog(hwnd, 0);
}
动态链接方法
vc++ 6.0 新建一个Win32 DialogBased Application 名字为dll动态链接
把 动态链接库.dll和动态链接库.lib两个文件 复制在工程的根目录下
#include "stdafx.h"
#include <windows.h>
#include <windowsx.h>
#include "resource.h"
#include "MainDlg.h"
typedef int(__cdecl* FunctionAdd)(int,int);
/*
Template designed by RuPeng.com. Please visit http://www.rupeng.com for more information
如鹏网(http://www.rupeng.com)大学生计算机学习社区,提供大量免费视频学习教程,提供个性化一对一学习指导
*/
BOOL WINAPI Main_Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
HANDLE_MSG(hWnd, WM_INITDIALOG, Main_OnInitDialog);
HANDLE_MSG(hWnd, WM_COMMAND, Main_OnCommand);
HANDLE_MSG(hWnd,WM_CLOSE, Main_OnClose);
}
return FALSE;
}
BOOL Main_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam)
{
return TRUE;
}
void Main_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
switch(id)
{
case IDC_OK:
{
HMODULE hModule;
FunctionAdd add;
hModule = LoadLibrary("动态链接库.dll");//调试时hModule 为0x10000000
if(NULL==hModule )
{
MessageBox(hwnd,TEXT("加载失败"),TEXT("提示"),MB_OK|MB_ICONERROR);
//error.
}
add =(FunctionAdd)GetProcAddress(hModule,"add");
if(NULL==add)
{
MessageBox(hwnd,TEXT("没有add方法"),TEXT("提示"),MB_OK|MB_ICONERROR);
//error
}
int r = add(1,1);
TCHAR str[256];
wsprintf(str,"1+1=%d",r);
MessageBox(hwnd,str,TEXT("提示"),MB_OK);
FreeLibrary(hModule);
//MessageBox(hwnd,TEXT("欢迎访问如鹏网 www.RuPeng.com 大学生计算机学习社区"),TEXT("问好"),MB_OK);
}
break;
default:
break;
}
}
void Main_OnClose(HWND hwnd)
{
EndDialog(hwnd, 0);
}
静态链接和动态链接的用途:
静态链接:一定要有dll链接库才可以运行
动态链接:没有dll也可以运行,只是某些功能不能用,例如:插件