VC++动态/静态链接库 【3】
来源:互联网 发布:wkwebview js交互demo 编辑:程序博客网 时间:2024/06/04 18:04
Win32 Dll 的创建和调用:
1. 创建:
在VC中创建project: Win32 Dynamic-Link Library: win32Dll
*.cpp 的内容与上节中的静态链接库一样,不同的是头文件的实现:
动态链接库:extern "C" int __declspec(dllexport)add(int x, int y);//声明add为dll的导出函数。
静态链接库:extern "C" int add(int x, int y);
编译生成 win32Dll.lib 和 win32Dll.dll
2. 调用:
动态调用步骤如下:
(1) 定义函数指针:
typedef int (* FunPtr)(int,int);
FunPtr addFun;
(2) 加载动态链接库:
Handle handle =LoadLibrary("win32Dll.dll");
(3) 获取函数指针调用函数:
addFun =(FunPtr)GetProcAddress(handle ,"Add");
int res = addFun(2,3); // 2+3;
(4) 释放动态链接库:
FreeLibrary(handle); // 释放载入的动态库
静态调用:
#pragma comment(lib,"win32Dll.lib") //告诉编译器lib文件所在的路径。
extern "C" __declspec(dllimport) add(int x,int y);
win32Dll.lib 文件中包含了DLL 导出函数的符号名及序号(并不含有实际的代码),经过编译将这些信息与动态链接库的文件名一起编译到exe文件中。
当执行exe时,可以根据这些信息加载dll 并调用dll中的函数。
这样,EXE将能直接通过函数名调用DLL的输出函数,就象调用程序内部的其他函数一样。
3. dll 导出函数的声明:
采用__declspec 进行声明;
采用模块定义(.def) 文件声明:
必须在工程中加入lib.def文件:
; lib.def : 导出DLL函数
LIBRARY dllTest
EXPORTS
add @ 1
分号表示注释,dllTest 为dll名称;EXPORTS后列出要导出函数的名称,可以用@1表示导出函数的序号为1.
因此也可以这样调用库函数:
addFun =(FunPtr)GetProcAddress(handle , MAKEINTRESOURCE ( 1 ));
4. DllMain 函数:
windows 程序在加载dll库的时候,需要一个入口函数 DllMain, 默认调用缺省的DllMain 函数。
DllMain是Dll的内部函数,是被系统自动调用的,外部程序无法直接调用DllMain。
- ul_reason_for_call指明了被调用的原因。原因共有4种,即PROCESS_ATTACH、PROCESS_DETACH、THREAD_ATTACH和THREAD_DETACH。
- APIENTRY被定义为__stdcall,它意味着这个函数以标准Pascal的方式进行调用,也就是WINAPI方式;
- 进程中的每个DLL模块被全局唯一的32字节的HINSTANCE句柄标识,只有在特定的进程内部有效,句柄代表了DLL模块在进程虚拟空间中的起始地址。在Win32中,HINSTANCE和HMODULE的值是相同的,这两种类型可以替换使用,这就是函数参数hModule的来历。
5. __stdcall 和__cdecl
如果通过VC++编写的DLL欲被其他语言编写的程序调用,应将函数的调用方式声明为__stdcall方式,WINAPI都采用这种方式,而C/C++缺省的调用方式却__cdecl。
__stdcall方式与__cdecl对函数名最终生成符号的方式不同。
若采用C编译方式(在C++中需将函数声明为extern "C"),__stdcall调用约定在输出函数名前面加下划线,后面加“@”符号和参数的字节数,形如_functionname@number;
而__cdecl调用约定仅在输出函数名前面加下划线,形如_functionname。
#define CALLBACK __stdcall //这就是传说中的回调函数
#define WINAPI __stdcall //这就是传说中的WINAPI
#define WINAPIV __cdecl
#define APIENTRY WINAPI //DllMain的入口就在这里
#define APIPRIVATE __stdcall
#define PASCAL __stdcall
在lib.h中,应这样声明add函数:
int __stdcall add(int x, int y);
在应用工程中函数指针类型应定义为:
typedef int(__stdcall *lpAddFun)(int, int);
若在lib.h中将函数声明为__stdcall调用,而应用工程中仍使用typedef int (* lpAddFun)(int,int),运行时将发生错误(因为类型不匹配,在应用工程中仍然是缺省的__cdecl调用)
导出函数
/////////////////////////////////////////////////////////////////////////////////////////
#ifndef LIB_H
#define LIB_H
extern "C" int __declspec(dllexport)add(int x, int y);
#endif
////////////////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "lib.h"
int add(int x, int y)
{
return x + y;
}
/////////////////////////////////////////////////////////////////////////////////////////////////
【注】windows and linux 动态/静态链接库 学习整理系列
参考资料:http://pcedu.pconline.com.cn/empolder/gj/vc/
- VC++动态/静态链接库 【3】
- VC++动态/静态链接库 【1】
- VC++动态/静态链接库 【2】
- VC++动态/静态链接库 【4】
- vc 动态链接库和静态链接库
- vc 动态链接库和静态链接库
- VC的静态链接库 & 动态链接库
- VC下静态链接库与动态链接库
- 【VC++DLL动态链接库编程】VC++静态库编译(3)
- VC中怎么加载静态和动态链接库
- VC生成动态链接库+静态调用---window
- 动态链接库、静态链接库;动态链接、静态链接
- 动态链接,静态链接,动态链接库,静态链接库
- 静态动态链接库
- 动态+静态链接库
- 动态静态链接库
- VC++动态链接库
- VC++ 动态链接库
- 使用ByteArray及AMF来提高Data Object的操作效率
- 巧妙去掉QQ聊天窗口的广告
- Flex Viewer 开发教程(7)Widget与服务器交互
- linux 的一些工具 技巧
- Visual Studio IDE 实用小技巧
- VC++动态/静态链接库 【3】
- 迭代,敏捷开发和UP
- 一个绑定amf数据的例子
- 在SSH jdk6.0 Tomcat6.0环境中使用CXF 运行时报错
- 以命令方式更改IP地址
- Flex Viewer 开发教程 完整版 (pdf + source code)
- 【卷首语】大话软件开发——献给开发初学者或是在开发中迷失的人们
- mysqd实例服务hang住的检测思路及方案
- Android ADB的使用