关于使用Visual编译静态库动态库及其使用的问题
本文主要讲述了如何使用Visual Studio 2013 编译静态库和动态库,并使用。
一、静态库
1、 编写静态库
若要创建将引用并使用刚创建的静态库的应用程序,请从“文件”菜单中选择“新建”,然后选择“项目”。
A 在“项目类型”窗格中,选择“Visual C++”下的“Win32”。
B 在“模板”窗格中,选择“Win32 控制台应用程序”。
C 为项目选择一个名称(如 MyExecRefsLib),并将其键入“名称”字段。 在“解决方案”旁边的下拉列表框中选择“添入解决方案”。 这会将新项目添加到该静态库所属的同一个解决方案中。
D单击“确定”启动“Win32 应用程序向导”。 在“Win32 应用程序向导”对话框的“概述”页中,单击“下一步”。
E 在“Win32 应用程序向导”的“应用程序设置”页中,选择“应用程序类型”下的“控制台应用程序”。
F 在“Win32 应用程序向导”的“应用程序设置”页中,清除“附加选项”下的“预编译头”。
单击“完成”创建项目。
然后新建一个头文件一个源文件如下:
// 头文件
#pragma once
// MathLIB.h
namespace MathFuncs
{
class MyMathFuncs
{
public:
// Returns a + b
static double Add(double a, double b);
// Returns a - b
static double Subtract(double a, double b);
// Returns a * b
static double Multiply(double a, double b);
// Returns a / b
// Throws DivideByZeroException if b is 0
static double Divide(double a, double b);
};
}
//源文件
#include <stdexcept>
#include "MathLIB.h"
namespace MathFuncs
{
double MyMathFuncs::Add(double a, double b)
{
return a + b;
}
double MyMathFuncs::Subtract(double a, double b)
{
return a - b;
}
double MyMathFuncs::Multiply(double a, double b)
{
return a * b;
}
double MyMathFuncs::Divide(double a, double b)
{
if (b == 0)
{
throw new std::invalid_argument("b cannot be zero!");
}
return a / b;
}
}
添加完你自定义的接口后,直接编译。在Debug(Release)下得到TestLIB.lib文件。至此,你的静态库生成完毕。
2、 使用静态库
使用 #pragma comment导入lib库
#include "..\\myLib\\MathLIB.h"
#pragma comment(lib,"..\\myLib\\TestLIB.lib")
int _tmain(int argc, _TCHAR* argv[])
{
double a = 6.3;
double b = 2;
double res = MathFuncs::MyMathFuncs::Add(a, b);
printf("%f", res);
return 0;
}
注意,这里的#pragma comment一定要在include头文件之后。
如果你不想使用相对路径,你可以在下面的目录中加入你头文件和静态库的路径。
然后,你就可以直接导入头文件和LIB库文件了。
二、动态库
使用lib需注意两个文件:
•.h头文件,包含lib中说明输出的类或符号原型或数据结构。应用程序调用lib时,需要将该文件包含入应用程序的源文件中。
•.LIB文件。
使用dll需注意三个文件:
•.h头文件,包含dll中说明输出的类或符号原型或数据结构的.h文件。应用程序调用dll时,需要将该文件包含入应用程序的源文件中。
•.LIB文件,是dll在编译、链接成功之后生成的文件,作用是当其他应用程序调用dll时,需要将该文件引入应用程序,否则产生错误(如果不想用lib文件或者没有lib文件,可以用WIN32 API函数LoadLibrary、GetProcAddress装载)。
•dll文件,真正的可执行文件,开发成功后的应用程序在发布时,只需要有.exe文件和.dll文件,并不需要.lib文件和.h头文件。
注意,Dll中的LIB文件和静态库中的LIB文件不是一回事。Dll中的LIB文件是第三方应用程序调用Dll的一个桥梁,而静态库中的LIB文件是库文件。
1、创建动态库
#pragma once
//头文件
namespace MathCalculate
{
class MyMath
{
public:
static int add(int a, int b);
};
}
// cpp文件
#include "Calculate.h"
int MathCalculate::MyMath::add(int a, int b)
{
return a + b;
}
除此之外,还需要添加一个def文件,来导出函数接口,
LIBRARY "MyDll"
EXPORTS
add @1
编译完成,Debug(Release)目录下即有相关的Dll库和中间文件lib。
3、 如何使用dll文件呢。
Lib文件和头文件使用同静态库一致,唯一需要主要的是,我们需要把Dll文件放在系统目录(C:\Windows\SysWOW64或者C:\Windows\System32)或者当前可执行文件的同一级目录下。
题外话:VC++工程中的基本路径是Debug(Release)路径,使用相对路径时,指得就是这个路径。同时,include中的路径可以不用使用转义字符,但是pragma comment中的路径必须要使用转义字符。
#include "..\myDll\Calculate.h"
#pragma comment(lib, "..\\myDll\\MyDll.lib")
这样写是可以的。
注意 静态库和动态库在导出时的区别
静态库不需要export 但是动态库需要
如果你使用extern "C"定义你的导出函数
dll中定义的接口如下:
extern "C" __declspec(dllexport)
int add(int a, int b);