Visual Stdio 动态库的生成

VS 下面生成动态库时,只需要在项目向导中最后一步选择是生成dll文件或者在创建项目后在项目->属性中设置生成的属性为dll。

关键是如何使用生成的dll。VS在生成dll时默认是不生成对应的导入库lib的。需要自己定义需要导入的函数。文件类型为.def。

.def的添加方式为项目属性-->连接器-->输入-->模块定义文件,输入source.def。


MSDN上的介绍


网上的资料:

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的输出函数,就象调用程序内部的其他函数一样。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值