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 <iostream>
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:

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

测试:

#include <iostream>
using namespace std;
#include "func.h"

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

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

    system("pause");
    return 0;
}

结果:

 

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 <iostream>
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 <iostream>
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;
}

执行结果:

 

  • 31
    点赞
  • 130
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
Python DLL 是通过使用 ctypes 或 cffi 等模块来调用在 C 或 C++ 中编写的动态链接库。而在 Python DLL导出,可以作为一个模块调用或者在其他 Python 脚本中实例化使用。 在 C 或者 C++ 中,我们可以使用导出函数的方式来将导出DLL 中的函数。在 Python 中,我们可以使用 ctypes 模块来加载 DLL,并且使用函数指针方式来访问导出。 首先,我们需要得到 DLL 文件的路径,并使用 ctypes 的 cdll 或者 WinDLL 函数加载 DLL。然后,使用 ctypes 的 POINTER 函数来创建指向的指针型。接着,我们可以使用 getattr 函数来获取 DLL导出的函数,并将其转换为 Python 中的函数。最后,我们使用指针来实例化导出,并调用其中的方法。 以下是一个示例代码: ```python import ctypes # 加载 DLLdll = ctypes.WinDLL('example.dll') # 创建指向的指针型 ClassPtr = ctypes.POINTER(ctypes.c_void_p) # 获取 DLL导出函数 get_class = getattr(dll, 'get_class') get_class.restype = ClassPtr # 实例化导出 c = get_class() # 调用中的方法 # 假设导出中有一个名为 foo 的函数 foo = getattr(dll, 'foo') foo.argtypes = [ClassPtr] foo.restype = ctypes.c_void_p result = foo(c) ``` 通过以上方法,我们就能够在 Python 中调用通过 DLL 导出了。当然,在实际应用中,我们需要根据实际情况进行相应的参数配置和错误处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

深山里的小白羊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值