当前位置:网站首页>实现动态库(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);
}
运行截图

总结
至此,虽然开头提及因对象依赖关系不当而导致野指针引用的问题仍然没有得到解决,但却离成功更近了一步。现在能够保证,在任何动态库之间使用接口创建或回收内存,通常不会系统报错。
边栏推荐
猜你喜欢
随机推荐
uniCloud通讯录实战
【Popular Science Post】Detailed explanation of MDIO interface
PCB设计思路
倍福ET2000侦听器使用
树莓派4B打开文件管理时出现闪退
ArrayList LinkList效率对比
ICN6211:MIPI DSI转RGB视频转换芯片方案介绍 看完涨知识了呢
Comparative analysis of mobile cloud IoT pre-research and Alibaba Cloud development
写博客的原因。
sacalatest AnyFunSuite:no implicits found for parameter pos
USB HUB USB集线器电路设计
无向图的连通分支数(并查集)
USB2.0一致性测试方法_高速示波器
【科普贴】I2C接口详解——偏硬件解析
Comparative analysis of OneNET Studio and IoT Studio
【科普贴】SD卡接口协议详解
78XX 79XX多路输出电源
使用批处理脚本修改hosts文件
[Arduino connects the clock module to display the time on LCD1602]
【Arduino使用旋转编码器模块】









