一、开发环境:Visual Studio 2012(其他版本亦可)
二、生成动态和静态链接过程:
1、新建Win32项目,代码使用的是工厂方法模式,点击确认按钮
点击“下一步”
应用程序类型勾选“DLL”,点击“完成”
2、代码中可看到自动生成了dllmain.cpp文件,里面的DllMain函数是主入口函数
打开项目属性页,如有必要,可将字符集设为多字节字符集
在C/C++ 预处理器中,可以看到VS自动添加的宏定义(名称与项目名称一致),可用之进行dll导出或导入
3、源代码
【注】__declspec(dllexport)是导出库文件,__declspec(dllimport)是导入库文件
Product.h
#pragma once
#ifdef FACTORYMETHODMODE_EXPORTS
#define FACTORYMETHODMODE_API __declspec(dllexport)
#else
#define FACTORYMETHODMODE_API __declspec(dllimport)
#endif
// 抽象产品类
class FACTORYMETHODMODE_API Product
{
public:
virtual ~Product();
virtual void Operation() const = 0;
};
// 具体产品类A
class FACTORYMETHODMODE_API ConcreteProductA : public Product
{
public:
~ConcreteProductA();
void Operation() const override;
};
// 具体产品类B
class FACTORYMETHODMODE_API ConcreteProductB : public Product
{
public:
~ConcreteProductB();
void Operation() const override;
};
Product.cpp
#include "stdafx.h"
#include "Product.h"
#include <iostream>
Product::~Product()
{
std::cout << "Product destruction.\n";
}
ConcreteProductA::~ConcreteProductA()
{
std::cout << "ConcreteProductA destruction.\n";
}
void ConcreteProductA::Operation() const
{
std::cout << "ConcreteProductA Operation\n";
}
ConcreteProductB::~ConcreteProductB()
{
std::cout << "ConcreteProductB destruction.\n";
}
void ConcreteProductB::Operation() const
{
std::cout << "ConcreteProductB Operation\n";
}
Creator.h
#pragma once
#ifdef FACTORYMETHODMODE_EXPORTS
#define FACTORYMETHODMODE_API __declspec(dllexport)
#else
#define FACTORYMETHODMODE_API __declspec(dllimport)
#endif
#include "Product.h"
// 抽象创建者类
class FACTORYMETHODMODE_API Creator
{
public:
Creator();
virtual ~Creator();
// 工厂方法
virtual Product* FactoryMethod() = 0;
void SomeOperation();
protected:
Product *m_product;
};
// 具体创建者A
class FACTORYMETHODMODE_API ConcreteCreatorA : public Creator
{
public:
ConcreteCreatorA();
~ConcreteCreatorA();
Product* FactoryMethod() override;
};
// 具体创建者B
class FACTORYMETHODMODE_API ConcreteCreatorB : public Creator
{
public:
ConcreteCreatorB();
~ConcreteCreatorB();
Product* FactoryMethod() override;
};
Creator.cpp
#include "stdafx.h"
#include "Creator.h"
#include <iostream>
Creator::Creator()
: m_product(nullptr)
{
}
Creator::~Creator()
{
std::cout << "Creator destruction.\n";
if (m_product)
{
delete m_product;
m_product = nullptr;
}
}
void Creator::SomeOperation()
{
Product* product = this->FactoryMethod();
if (product) {
product->Operation();
}
}
ConcreteCreatorA::ConcreteCreatorA()
: Creator()
{
}
ConcreteCreatorA::~ConcreteCreatorA()
{
std::cout << "ConcreteCreatorA destruction.\n";
}
Product* ConcreteCreatorA::FactoryMethod()
{
if (nullptr == m_product) {
m_product = new ConcreteProductA();
}
return m_product;
}
ConcreteCreatorB::ConcreteCreatorB()
: Creator()
{
}
ConcreteCreatorB::~ConcreteCreatorB()
{
std::cout << "ConcreteCreatorB destruction.\n";
}
Product* ConcreteCreatorB::FactoryMethod()
{
if (nullptr == m_product) {
m_product = new ConcreteProductB();
}
return m_product;
}
4、选择Debug或Release编译,即可生成lib和dll文件,如下图所示:
至此,动态链接和静态连接库已生成,将它们拷贝到其他工程中即可使用。
三、调用动态、静态链接库
1、新建一个测试工程,博主建的是一个名为“UseDllTest”的控制台程序。
2、将FactoryMethodMode.lib和FactoryMethodMode.dll文件拷贝到编译目录下,需要注意的是如果UseDllTest使用Debug编译,那就拷贝FactoryMethodMode项目中Debug生成的库文件,如果UseDllTest使用Release编译,那就拷贝FactoryMethodMode项目中Release生成的库文件,否则混用的话可能有些问题。
3、将FactoryMethodMode库文件中用到的头文件拷贝到当前项目中:
4、源代码
UseDllTest.cpp
#include "stdafx.h"
#include "..\lib\Creator.h"
#include "..\lib\Product.h"
#pragma comment(lib, "FactoryMethodMode.lib")
int _tmain(int argc, _TCHAR* argv[])
{
Creator *creatorA = new ConcreteCreatorA();
creatorA->SomeOperation();
Creator *creatorB = new ConcreteCreatorB();
creatorB->SomeOperation();
delete creatorA;
creatorA = nullptr;
delete creatorB;
creatorB = nullptr;
return 0;
}
也可以在项目属性页中添加库文件,它与在代码中添加#pragma comment(lib, "FactoryMethodMode.lib")是一样的效果
5、运行结果如下: