VS 下面生成动态库时,只需要在项目向导中最后一步选择是生成dll文件或者在创建项目后在项目->属性中设置生成的属性为dll。
关键是如何使用生成的dll。VS在生成dll时默认是不生成对应的导入库lib的。需要自己定义需要导入的函数。文件类型为.def。
.def的添加方式为项目属性-->连接器-->输入-->模块定义文件,输入source.def。
网上的资料:
1.DLL声明导出函数
DLL中导出函数的声明有两种方式:一种为在函数声明中加上__declspec(dllexport);另外一种方式是采用模块定义(.def) 文件声明,.def文件为链接器提供了有关被链接程序的导出、属性及其他方面的信息。
1)函数声明方式
#ifndef LIB_H
#define LIB_H
extern "C" int _declspec(dllexport) add(int x,int y);
#endif
函数实现
#include "add.h"
int add(int a, int b)
{
return a + b;
}
在另一个项目中引用项刚才生成的dll.当动态调用时,不需要加入函数头,因为是有编译器去dll可执行文件的符号表里面找有没有对应的函数。此时奇怪的是要用LoadLibraryA,可以找到,但是用LoadLibrary却返回是NULL,不知道是问什么?还有就是windows下编程是文件路径可以用两种方式:
1. F:/VS 2010 Projects/dll1/main/Debug/dll1.dll
2. F:\\VS 2010 Projects\\dll1\\main\\Debug\\dll1.dll
但是不支持单独使用 \ 来分割路径,因为 \ 被处理时认为是转义字符。
#include <stdio.h>
#include <windows.h>
typedef int(*addfunc)(int, int);
int main()
{
HINSTANCE hdll;
addfunc add;
hdll = LoadLibraryA("F:\VS 2010 Projects\dll1\main\Debug\dll1.dll");
if (hdll != NULL)
{
add = (addfunc)GetProcAddress(hdll, "add");
if (add == NULL)
{
printf("can not find the function\n");
}
else
{
int res = add(1, 2);
printf("the ans is %d", res);
}
FreeLibrary(hdll);
}
return 0;
}
DLL的动态调用
由“LoadLibrary-GetProcAddress-FreeLibrary”系统Api提供的三位一体“DLL加载-DLL函数地址获取-DLL释放”方式.动态调用方式的特点是完全由编程者用 API 函数加载和卸载 DLL,程序员可以决定 DLL 文件何时加载或不加载,显式链接在运行时决定加载哪个 DLL 文件。动态调用方式相比静态调用,较复杂,但能更加有效地使用内存,是编制大型应用程序的重要方式。(
可以手动的释放加载到内存的动态库,提高内存利用率)
2)def方式
LIBRARY dll1
EXPORTS
add
函数声明,声明为外部函数。
#ifndef ADD_H
#define ADD_H
extern "C" int add(int x, int y);
#endif
静态方式加载动态库。
#include <stdio.h>
#include "../dll1/add.h"
#pragma comment(lib,"..\\Debug\\dll1.lib")
int main()
{
int res = add(1, 2);
printf("the ans is %d", res);
return 0;
}
静态调用采用#pragma comment(lib,"..\\Debug\\dll1.lib")方式导入。
静态调用方式的特点是由编译系统完成对DLL的加载和应用程序结束时 DLL 的卸载。当调用某DLL的应用程序结束时,若系统中还有其它程序使用该 DLL,则Windows对DLL的应用记录减1,直到所有使用该DLL的程序都结束时才释放它。静态调用方式简单实用,但不如动态调用方式灵活。
静态调用方式不再需要使用系统API来加载、卸载DLL以及获取DLL中导出函数的地址。这是因为,当程序员通过静态链接方式编译生成应用程序时,应用程序中调用的与.lib文件中导出符号相匹配的函数符号将进入到生成的EXE 文件中,.lib文件中所包含的与之对应的DLL文件的文件名也被编译器存储在 EXE文件内部。当应用程序运行过程中需要加载DLL文件时,Windows将根据这些信息发现并加载DLL,然后通过符号名实现对DLL 函数的动态链接。这样,EXE将能直接通过函数名调用DLL的输出函数,就象调用程序内部的其他函数一样。