当前位置: 首页 > news >正文

VS2015与dll库和lib库的生成和管理

本节内容将是一个较长篇的内容,研究如何实现生成自己的dll库以及其中的一些细节。

目录

最直接的方法——新建dll库工程

间接方案——修改已有工程

定义变量到库中

定义包含类的DLL库


最直接的方法——新建dll库工程

然后就可以生成了,鉴于后续操作和非直接方案一模一样,所以这里就不再赘述,现在我们要了解的是,如何把以前构建好的工程修改为dll库生成工程。

间接方案——修改已有工程

我们进入一个工程目录里,注意该工程的目录:

黄圈里表示解决方案名,红圈里表示解决方案里的其中一个工程,我们把它拷贝到别的解决方案里(就是实现一个多工程的解决方案)。

我们要进行学习的工程目录下有三个工程,都包含在这个解决方案里:

现在我们设置winTest为工程启动项(右键工程,set as SetUp Project):

然后主要是拷贝一个文件进来(从直接建立的dll工程里拷贝过来):

这就相当于是dll库工程的main函数文件。

右键该工程属性,修改

然后在需要编译生成到库里的文件命名为:

#ifndef  _MATH_H_
#define _MATH_H_

#if (defined WIN32 || defined _WIN32 || defined WINCE)
#define MYDLL __declspec(dllexport)
#else
#define PROJ_EXPORTS
#endif // (WIN32)

// 生成dll库的函数
MYDLL void printInfo();
MYDLL float add(float a, float b);
MYDLL float sub(float a, float b);

#endif

以及这些函数需要被实现:

#include "stdafx.h"
#include "Math.h"
#include <iostream>

void printInfo()
{
	std::cout << "hahahahahaah" << std::endl;
}

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

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

这是编译工程,就可以正确输出dll文件了:

我的解决方案名是ProjectTest,从上面的路径就可以找到生成的库。

我们把这些库拷贝到别的工程里:winTest.dll winTest.lib

下面开始测试在File这个工程里引用它:

我们引用之前的头文件:

#include <iostream>
#include "../winTest/Math.h"

int main() {


	return 0;
}

因为这两个库都在我们目录下,能直接访问到,所以写上附加的依赖项:

然后输入完整程序:

#include <iostream>
#include "../winTest/Math.h"

int main()
{
	float aa = 1.0f, bb = 12.5f;
	printInfo();
	std::cout << sub(bb, aa) << std::endl;
	std::cout << "ssss" << std::endl;
	system("pause");

}

结果正确输出了。

定义变量到库中

现在有个问题,有些时候我们喜欢写一些变量到文件里,这个时候生成库应该怎么做呢?

我们修改一下之前的Math.cpp文件:

#include "stdafx.h"
#include "Math.h"
#include <iostream>

float bbes = 17.5;
void printInfo()
{
	std::cout << "DLL Test:"<< bbes << std::endl;
}

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

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

然后重复上面的操作,然后发现成功打印了出来:

也就是说,这个变量的值也被编译到了库中。我们再修改一下头文件:

然后回到我们用来测试运行的工程,把main改一下:

运行,报错:

所以仅仅只有值被编译到了库中,而该变量并没有被编译到库里。

我们删掉头文件里面的extern声明,在测试工程的文件里加入:

测试证明,编译到链接库里面并没有该变量,连该变量的名称索引信息都不存在,而只是作为一个值保存在了库内。

定义包含类的DLL库

在生成库工程的Math.h中继续写:

class MYDLL Point;
class Point{
public:
	Point(float a,float b) {
		x = a; y = b;
	}
	void add(Point);
	void sub(Point);
	void print();
	float x, y;
};

以及在cpp文件中写入:

void Point::add(Point b)
{
	x += b.x;
	y += b.y;
}
void Point::sub(Point b)
{
	x -= b.x;
	y -= b.y;
}

void Point::print()
{
	std::cout << "x:" << x << ",y:" << y << std::endl;
}

重复库文件拷贝到测试目录的步骤,然后测试结果:

类的测试也是正确的。

相关文章:

  • 微积分 重难点记录 三 无穷远处的极限与水平渐近线 + 画曲线的总结
  • 微积分 重难点记录 二 微积分的理论基础 + 不定积分和净变化理论
  • 全局体渲染光照技术总结概括(截止到2014年)
  • 再学一周光线追踪 bvh树流程
  • 微积分 重难点记录 三 替代法则
  • CUDA拷贝二维数组到GPU内存中
  • 微积分 重难点记录 一 曲线间的面积 + 体积
  • 多重重要性采样(MIS)与光线追踪技术
  • VTK体渲染应用实例:读取并可视化MHD数据的程序
  • CUDA Handbook 关于CUDA的硬件架构和软件架构的详细解读
  • CUDA Handbook CUDA的硬件架构
  • 使用OpenMP进行多线程加速for循环
  • 半角切片阴影 half-angle slice based —— 全网最好和最易懂的算法描述
  • 什么是shader aliasing着色器走样
  • 微积分 重难点记录 二 三角替换 + 通过部分分式分解的有理函数积分
  • “大数据应用场景”之隔壁老王(连载四)
  • co模块的前端实现
  • HTTP--网络协议分层,http历史(二)
  • Java读取Properties文件的六种方法
  • js
  • JS基础之数据类型、对象、原型、原型链、继承
  • Linux编程学习笔记 | Linux IO学习[1] - 文件IO
  • MySQL数据库运维之数据恢复
  • Node 版本管理
  • npx命令介绍
  • PAT A1120
  • Python学习笔记 字符串拼接
  • SegmentFault 社区上线小程序开发频道,助力小程序开发者生态
  • 仿天猫超市收藏抛物线动画工具库
  • 聊聊spring cloud的LoadBalancerAutoConfiguration
  • 前嗅ForeSpider采集配置界面介绍
  • 前嗅ForeSpider教程:创建模板
  • 三分钟教你同步 Visual Studio Code 设置
  • 想写好前端,先练好内功
  • 带你开发类似Pokemon Go的AR游戏
  • 智能情侣枕Pillow Talk,倾听彼此的心跳
  • ​决定德拉瓦州地区版图的关键历史事件
  • #ubuntu# #git# repository git config --global --add safe.directory
  • #图像处理
  • (31)对象的克隆
  • (C语言)输入一个序列,判断是否为奇偶交叉数
  • (二十三)Flask之高频面试点
  • (附源码)spring boot智能服药提醒app 毕业设计 102151
  • (附源码)springboot金融新闻信息服务系统 毕业设计651450
  • (附源码)计算机毕业设计SSM智能化管理的仓库管理
  • (教学思路 C#之类三)方法参数类型(ref、out、parmas)
  • (免费分享)基于springboot,vue疗养中心管理系统
  • (原創) X61用戶,小心你的上蓋!! (NB) (ThinkPad) (X61)
  • (转)JVM内存分配 -Xms128m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=512m
  • (轉貼) UML中文FAQ (OO) (UML)
  • (最简单,详细,直接上手)uniapp/vue中英文多语言切换
  • .NET 8.0 中有哪些新的变化?
  • .NETCORE 开发登录接口MFA谷歌多因子身份验证
  • .NET基础篇——反射的奥妙
  • .net通用权限框架B/S (三)--MODEL层(2)