栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

win32程序静态库与动态库的开发与使用

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

win32程序静态库与动态库的开发与使用

1、静态库开发

新建一个项目

选择静态库

然后创建两个文件testlib.h和testlib.cpp

testlib.h

#pragma once

int add(int a, int b);

testlib.cpp

#include "testlib.h"

int add(int a, int b)
{
	return a + b;
}

直接编译生成,就会生成一个静态库文件

开发完成后,我们只需要把testlib.h头文件和testlib.lib库提供给别人就可以了。

2、静态库使用 

新建一个项目

 选择控制台应用程序

 新建一个文件test001.cpp文件

然后把步骤1中那个testlib.h头文件和testlib.lib库文件拷贝到当前工程目录下

如果你的lib库没有在当前工程目录下,还需要再选择附加库目录

 

 选择到testlib.lib所在目录下

 最后在test001.cpp引入头文件和库文件,就可以调用静态库中提供的函数

#include 
#include 

//引入静态库的头文件
#include "testlib.h"

#pragma comment(lib, "testlib.lib")

int main() {

	int num1 = 12;
	int num2 = 24;

	int sum = add(num1, num2);
	printf("sum = %dn", sum);

	system("pause");
	return 0;
}
3、动态库开发

新建一个项目

选择dll

 

创建两个文件testdll.h和testdll.cpp

testdll.h

#pragma once



#ifdef _DLLAPI
#define DLLAPI _declspec(dllexport) 
#else
#define DLLAPI _declspec(dllimport)
#endif

//注意这里要使用extern "C"去声明,用c编译器去编译
//因为我们知道,c++有多态,c++编译器编译函数时,不仅会把名字编译进去,把参数个数和类型也会编译进去
//因此,如果用c++编译器编译,除了函数名还有其他一些特殊符号。下面会给大家展示下
extern "C" DLLAPI int add(int a, int b);

extern "C" DLLAPI int sub(int a, int b);

 testdll.cpp

#include "testdll.h"

int add(int a, int b)
{
	return a + b;
}

int sub(int a, int b)
{
	return a - b;
}

由于_DLLAPI没有定义,所以现在使用的是#define DLLAPI _declspec(dllimport) ,但我们现在需要的#define DLLAPI _declspec(dllexport),所以要去预定义_DLLAPI

 添加这个定义

最后直接生成,会生成一个静态库和一个动态库

 

 在这里给大家介绍windows下查看动态库的一个工具:Dependencywalker,可以使用该工具查看动态库提供的函数以及动态库的依赖。

下载地址:Dependency Walker (depends.exe) Home Pagehttp://www.dependencywalker.com/打开后,我们把刚才生成的动态库拖进去,可以看到库的依赖和库中提供的函数

 

这里注意下,如果刚才testdll.h中不用extren “C”声明。那么编译出来的库文件中函数名就是下面这样的。这是因为是用c++编译器编译的。

4、动态库的使用

动态库使用有两种方法

4.1、方法1(隐式调用)

创建一个控制台项目

 

新建一个文件test002.cpp 

然后把步骤3中的testdll.h文件以及testdll.lib和testlib.lib拷贝到当前工程目录

 test002.cpp

#include 
#include 
#include "testdll.h"

//隐式调用动态库
#pragma comment(lib, "testdll.lib") 

int main() {

	int data1 = add(1, 2);
	int data2 = sub(3, 6);

	printf("data1 = %d, data2 = %dn", data1, data2);

	system("pause");
	return 0;
}
4.2、方法2(显式调用)

显示调用时,也要把步骤3中的testdll.h文件以及testdll.lib和testlib.lib拷贝到当前工程目录

test002.cpp

#include 
#include 
#include "testdll.h"
#include  

typedef int(*PADD)(int a, int b);
typedef int(*PSUB)(int a, int b);

int main() {

	//加载动态库
	HMODULE hDll = LoadLibrary(L"testdll.dll");
	if (hDll == NULL) {
		printf("加载testdll.dll失败n");
		return -1;
	}

	//获取动态库中函数地址
	PADD pAdd = (PADD)GetProcAddress(hDll, "add");
	if (pAdd == NULL) {
		printf("获取add地址失败n");
		return -1;
	}

	PSUB pSub = (PADD)GetProcAddress(hDll, "sub");
	if (pSub == NULL) {
		printf("获取sub地址失败n");
		return -1;
	}

	int data1 = pAdd(1, 2);
	int data2 = pSub(3, 6);

	printf("data1 = %d, data2 = %dn", data1, data2);

	//释放
	FreeLibrary(hDll);

	system("pause");
	return 0;
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/702648.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号