当前位置:网站首页>实现动态库(DLL)之间内存统一管理
实现动态库(DLL)之间内存统一管理
2022-08-02 03:29:00 【ChivenZhang】
问题背景
公司里出现了这么个亟待解决的问题,就是项目中的多个动态库在释放时,由于顺序不当产生使用已析构对象野指针引用问题,导致系统崩溃。因此,个人认为解决这个难题的前提是使用统一的动态库负责内存分配与回收。
注释:对于所有DLL都是以MD编译模式生成,则不存在内存于A堆创建,B堆释放的风险。DLL统一分配仅仅适用于MT编译的模块代码。
设计思路
统一内存管理模块包括:内存分配模块(PMemory.dll),动态库加载模块(PExport.lib),业务模块(PService.exe或dll),其中
PMemory.dll
内存统一分配单元,提供统一的new与delete接口。
PExport.lib
封装动态加载与释放PMemory.dll的逻辑,简化代码编写工作。
PService.[exe/dll/lib]
具体业务逻辑单元。
实现代码
PMemory.dll
#include "PMemory.h"
#include <stdlib.h>
void* p_new(size_t size)
{
return ::malloc(size);
}
void p_delete(void* address)
{
::free(address);
}
PExport.lib
#include "PExport.h"
#include <Windows.h>
#include <stdlib.h>
class _Initial
{
public:
using FunctionNew = void* (*)(size_t);
using FunctionDelete = void (*)(void*);
public:
_Initial() : m_Handle(nullptr), m_FunctionDelete(nullptr), m_FunctionNew(nullptr)
{
m_Handle = ::LoadLibraryA("PMemory.dll");
if (m_Handle)
{
m_FunctionNew = (FunctionNew) ::GetProcAddress(m_Handle, "p_new");
m_FunctionDelete = (FunctionDelete) ::GetProcAddress(m_Handle, "p_delete");
}
}
~_Initial()
{
if (m_Handle)
{
m_FunctionNew = nullptr;
m_FunctionDelete = nullptr;
::FreeLibrary(m_Handle);
m_Handle = 0;
}
}
void* _new(size_t size)
{
if (m_FunctionNew)
{
return m_FunctionNew(size);
}
return nullptr;
}
void _delete(void* address)
{
if (m_FunctionDelete)
{
m_FunctionDelete(address);
}
}
private:
HMODULE m_Handle;
FunctionNew m_FunctionNew;
FunctionDelete m_FunctionDelete;
};
_Initial g_Memory;
void* p_malloc(size_t size)
{
return g_Memory._new(size);
}
void p_free(void* address)
{
g_Memory._delete(address);
}
void p_delete(void* address)
{
g_Memory._delete(address);
}
PService.exe
#include <PExport.h>
class A
{
public:
A(int n, int m) : a(n), b(m) {}
int a = 123;
int b = 321;
};
void main()
{
auto a = p_new<A>(666, 999);
printf("%d %d", a->a, a->b);
p_delete(a);
}
运行截图
总结
至此,虽然开头提及因对象依赖关系不当而导致野指针引用的问题仍然没有得到解决,但却离成功更近了一步。现在能够保证,在任何动态库之间使用接口创建或回收内存,通常不会系统报错。
边栏推荐
猜你喜欢
与TI的lvds芯片兼容-GM8284DD,GM8285C,GM8913,GM8914,GM8905C,GM8906C,国腾振芯LVDS类芯片,
[Arduino connected to GP2Y1014AU0F dust sensor]
同时求最大值与最小值(看似简单却值得思考~)
Comparative analysis of mobile cloud IoT pre-research and Alibaba Cloud development
【MQ-2 可燃气体和烟雾传感器与 Arduino 配合使用】
NE5532运放加法器
从Attention到Self-Attention和Multi-Head Attention
倍福ET2000侦听器使用
HDMI转MIPI CSI东芝转换芯片-TC358743XBG/TC358749XBG
龙讯LT6911系列C/UXC/UXB/GXC/GXB芯片功能区别阐述
随机推荐
Transformer结构解析及常见问题
【Arduino连接时钟模块在LCD1602上显示时间】
【MQ-2 可燃气体和烟雾传感器与 Arduino 配合使用】
振芯科技GM8285C:功能TTL转LVDS芯片简介
GM8284DD,GM8285C,GM8913,GM8914,GM8905C,GM8906C,国腾振芯LVDS类芯片
【树莓派入门(2)树莓派的远程控制】
[DS3231 RTC real-time clock module and Arduino interface to build a digital clock]
D类音频功放NS4110B电路设计
2019 - ICCV - 图像修复 Image Inpainting 论文导读《StructureFlow: Image Inpainting via Structure-aware ~~》
工业边缘网关究竟强大在哪里?
振芯GM7123C:功能RGB转VGA芯片方案简介
Typora use
振芯科技GM8285C:功能TTL转LVDS芯片简介
[Spark]-协同过滤
Modify hosts file using batch script
Arduino点亮数码管
AD PCB导出Gerber文件(非常详细的步骤)
Two-Stream Convolutional Networks for Action Recognition in Videos双流网络论文精读
【opencv】error: (-215:Assertion failed) ssize.empty() in function ‘cv::resize‘报错原因
Typora使用