8.DLL导出C++类

DLL中不仅可以导出函数和变量,也可以导出C++类。只需要在导出类名前关键字class后加上_declspec(dllexport),就可以实现导出类

1.DLL简单导出类代码

class _declspec(dllexport) Stu
{
public:
    Stu(int a);
    void print();

private:
    int _a;
};

实例:

.cpp文件:

// DynamicLib.cpp: 定义 DLL 应用程序的导出函数。
//

#include "stdafx.h"

#define _DLL_EXPORTS
#include "func.h"

#include 
using namespace std;

Stu::Stu(int a)
{
    this->_a = a;
}

void Stu::print()
{
    cout << _a << endl;
}

func.h文件:

#pragma once

#ifdef _DLL_EXPORTS
#define DLL_API _declspec(dllexport)
#else
#define DLL_API _declspec(dllimport)
#endif

class DLL_API Stu
{
public:
    Stu(int a);
    void print();

private:
    int _a;
};

在dependency中查看导出的DLL:

8.DLL导出C++类_第1张图片

可以发现,导出了四个函数,一个为构造函数、一个为拷贝构造函数、一个为析构函数,还有一个就是我们自己定义的print函数

测试:

#include 
using namespace std;
#include "func.h"

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

int main()
{
    Stu stu1(666);
    stu1.print();

    system("pause");
    return 0;
}

结果:

8.DLL导出C++类_第2张图片

 

2.简单导出类的缺点

这种简单导出类的方式,除了导出的东西太多、使用者对类的实现依赖太多以外,还有其他问题:必须保证使用同一种编译器。导出类的本质是导出类里的函数,因为语法上直接导出了类,没有对函数的调用方式、重命名进行设置,导致了产生的dll并不通用。

 

3.导出类的较好方式

定义一个抽象类(都是纯虚函数),调用者跟dll共用一个抽象类的头文件,dll中实现此抽象类的派生类,dll最少只需要提供一个用于获取抽象类对象指针的接口。

 

4.面向抽象设计优点

这种方式利用了C++类的虚函数,类似COM思想,采用接口跟实现分离,可以使得工程的结构更清晰,使用者只需要知道接口,而无需知道具体实现,产生的DLL通用没有特定环境限制。

 

5.注意事项

调用者跟DLL共用一个抽象类的头文件,调用者依赖于DLL的东西很少,只需要知道抽象类的接口,以及获取对象指针的导出函数,对象内存空间的申请和释放都在DLL模块中完成

 

6.代码演示

DLL生成代码:

.cpp文件:

// DynamicLib.cpp: 定义 DLL 应用程序的导出函数。
//

#include "stdafx.h"

#define _DLL_EXPORTS
#include "func.h"

#include 
using namespace std;

class Cat :public IAnimal
{
public:
	Cat()
	{
		cout << "Cat is created" << endl;
	}
	~Cat()
	{
		cout << "Cat is deleted" << endl;
	}
	virtual void eat()
	{
		cout << "Cats eat fish" << endl;
	}
	virtual void sleep()
	{
		cout << "Cats sleep" << endl;
	}
	virtual void delObj()
	{
		delete this;
	}
};

extern "C" DLL_API IAnimal *GetCat()
{
	return new Cat;
}

func.h文件:

#pragma once

#ifdef _DLL_EXPORTS
#define DLL_API _declspec(dllexport)
#else
#define DLL_API _declspec(dllimport)
#endif

class IAnimal
{
public:
	virtual void eat() = 0;
	virtual void sleep() = 0;
	virtual void delObj() = 0;
};

extern "C" DLL_API IAnimal *GetCat();

在dependency中查看导出的DLL:

发现导出的只有一个类名

调用者代码:

#include 
using namespace std;
#include "func.h"

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

int main()
{
	IAnimal *p = GetCat();
	p->eat();
	p->sleep();
	p->delObj();

	system("pause");
	return 0;
}

执行结果:

8.DLL导出C++类_第3张图片

 

你可能感兴趣的:(静动态链接库)