如何将含SomeInfo参数的自定义分配器传入PostGIS的lwgeom_set_handlers?
适配带上下文的内存分配器到PostGIS接口的解决方案
PostGIS的lwgeom_set_handlers要求的分配器签名没有上下文参数,而你的分配器依赖动态多实例的SomeInfo,不能用全局变量,这里可以通过**线程局部存储(TLS)**实现适配,核心思路是用TLS存储当前生效的SomeInfo,再写一个符合PostGIS签名的适配函数,内部从TLS取上下文调用你的分配器。
具体实现步骤
1. 定义线程局部存储的上下文变量
线程局部存储的变量每个线程独立拥有,完美支持多实例、动态切换的场景:
#include <thread> // 线程局部存储的SomeInfo,每个线程有独立副本 thread_local SomeInfo current_alloc_context; // 如果SomeInfo不可复制,改用指针存储 // thread_local SomeInfo* current_alloc_context_ptr = nullptr;
2. 编写适配函数
这个函数严格符合PostGIS要求的lwallocator签名,内部桥接你的自定义分配器:
// 适配PostGIS的分配器函数 void* postgis_alloc_adapter(size_t size) { // 从TLS取出当前上下文,调用你的分配器 return your_custom_allocator(current_alloc_context, size); // 如果用指针版本: // if (!current_alloc_context_ptr) return nullptr; // 错误处理 // return your_custom_allocator(*current_alloc_context_ptr, size); } // 同理适配free函数(如果PostGIS需要) void postgis_free_adapter(void* ptr) { your_custom_free(current_alloc_context, ptr); // 指针版本: // if (!current_alloc_context_ptr) return; // your_custom_free(*current_alloc_context_ptr, ptr); }
3. 在业务代码中切换上下文并设置Handlers
在需要使用特定SomeInfo实例的代码块中,先设置TLS变量,再配置PostGIS的内存处理函数:
// 假设有多个动态创建的SomeInfo实例 SomeInfo instanceA = {/* 初始化参数A */}; SomeInfo instanceB = {/* 初始化参数B */}; // 使用instanceA处理PostGIS操作 current_alloc_context = instanceA; lwgeom_set_handlers(postgis_alloc_adapter, postgis_free_adapter, /* 其他handler参数 */); // 执行需要PostGIS分配内存的操作(比如创建、处理LWGEOM对象) perform_postgis_operations_with_instanceA(); // 切换到instanceB处理 current_alloc_context = instanceB; lwgeom_set_handlers(postgis_alloc_adapter, postgis_free_adapter, /* 其他handler参数 */); perform_postgis_operations_with_instanceB();
关键注意事项
- 多线程安全:每个线程的TLS变量独立,不同线程可以同时使用不同的
SomeInfo实例,不会互相干扰。 - 上下文有效性:确保在调用PostGIS内存相关操作前,TLS变量已被正确初始化,避免使用未定义的上下文。
- 错误处理:可以在适配函数中添加上下文为空的判断,返回
nullptr或抛出异常,避免崩溃。
内容的提问来源于stack exchange,提问作者Jennifer Nissitta
相关产品推荐
相关产品推荐

