如何在KRTS内核中使用 STL
KRTS内核DLL是负责提供实时层功能实现。由于其核心地位,确保其稳定性和性能至关重要。然而,在早期版本中,KRTS内核DLL一直无法使用C++中的标准模板库(STL),这给开发带来了诸多不便,限制了开发者的生产力和代码的可维护性。
现在我可以很高兴的告诉大家,我们解决了这一问题,在内核中使用STL、类等等变得简单和轻松。下面我将通过一些示例代码来展示该功能如何实现。
STL的实现
想要实现在内核中使用STL,我们必须重新实现Allocator内存分配器并重载全局的 new 和 delete 操作符,如果有需要比较器也可以进行重载。
要求:
1. C++ 版本至少C++11或更高版本!
2. 仅支持内核层内部使用,不能用于共享内存中!
/**************************************************************************************
*
* 重载 new 和 delete 操作符:
* operator new 使用 KS_malloc 分配指定大小的内存块。
* operator delete 使用 KS_free 释放指定的内存块。
*
**************************************************************************************/
void* operator new(size_t allocateBlock){
void* pMemory;
// KS_malloc()函数是 KRTS提供的内存分配函数。
// 请勿在内核层使用C/C++提供的内存处理相关的方法!!!
KS_malloc(&pMemory, (uint)allocateBlock,0);
return pMemory;
}
void operator delete(void* pMemory) {
// KS_free()函数是 KRTS提供的内存析构函数。
KS_free(pMemory,0);
}
/**************************************************************************************
*
* 自定义分配器 KS_Allocator:
* 提供了模板类 KS_Allocator,用于管理类型 T 的内存分配和释放。
* allocate 方法使用 KS_malloc 分配内存,如果分配失败则抛出 std::bad_alloc 异常。
* deallocate 方法使用 KS_free 释放内存。
* PS: 内存分配虽然会抛出异常,请不要尝试在内核层使用try... catch..进行抓取!!!
*
*************************************************************************************/
template <typename T>
struct KS_Allocator {
using value_type = T;
// 构造函数
KS_Allocator() = default;
// 复制构造函数
template <typename U>
KS_Allocator(const KS_Allocator<U>&) {}
// 分配内存
T* allocate(std::size_t n) {
if (n == 0) {
return nullptr;
}
void* ptr = nullptr;
// 使用 KS_malloc 分配内存,注意第一个参数是指针的地址
KS_malloc(&ptr, n * sizeof(T), 0);
if (!ptr) {
throw std::bad_alloc();
}
return static_cast<T*>(ptr);
}
// 释放内存
void deallocate(T* p, std::size_t n) {
// 使用 KS_free 释放内存,注意第二个参数是 0
KS_free(p, 0);
}
template <typename U>
struct rebind {
using other = KS_Allocator<U>;
};
};
// 定义自定义分配器的比较运算符重载
template <typename T, typename U>
bool operator==(const KS_Allocator<T>&, const KS_Allocator<U>&) {
return true;
}
template <typename T, typename U>
bool operator!=(const KS_Allocator<T>&, const KS_Allocator<U>&) {
return false;
}
// 自定义比较器
struct KS_Compare {
template <typename T>
bool operator()(const T& a, const T& b) const {
return a < b; // 默认的比较器是小于
}
};
STL内核层实现并使用
// 使用自定义分配器的字符串类型
using KS_string = std::basic_string<char, std::char_traits<char>, KS_Allocator<char>>;
// 使用自定义分配器的vector类型
template <typename T>
using KS_vector = std::vector<T, KS_Allocator<T>>;
// 使用自定义分配器的map类型
template <typename Key, typename T, typename Compare = KS_Compare>
using KS_map = std::map<Key, T, Compare, KS_Allocator<std::pair<const Key, T>>>;
template <typename Key, typename T, typename Hash = std::hash<Key>, typename KeyEqual = std::equal_to<Key>>
using KS_unordered_map = std::unordered_map<Key, T, Hash, KeyEqual, KS_Allocator<std::pair<const Key, T>>>;
// 使用自定义分配器的set类型
template <typename Key, typename Compare = KS_Compare>
using KS_set = std::set<Key, Compare, KS_Allocator<Key>>;
// 使用自定义分配器的list类型
template <typename T>
using KS_list = std::list<T, KS_Allocator<T>>;
/**************************************************************************************
*
* 使用方法和C++标准库中的使用方式无异
*
*************************************************************************************/
// 字符串
KS_string str("Hello, KS_allocator!");
// vector
KS_vector<int> vec;
for (int i = 0; i < 1000000; i++) {
vec.push_back(i);
}
// map、pair
KS_map<int, KS_string> map;
map.insert(std::pair<int, KS_string>(1, "hello"));
map.insert(std::pair<int, KS_string>(2, "world"));
// set
KS_set<int> set;
set.insert(1);
set.insert(2);
// list
KS_list<int> list;
list.push_back(1);
list.push_back(2);