如何编写PostgreSQL的C++扩展?解决链接错误及文档需求
解决PostgreSQL C++扩展链接错误的方法
问题原因
你遇到的__gxx_personality_v0未定义符号错误,是因为编译链接C代码时未正确关联GNU C标准库,且Makefile中参数配置有误(-libstdc++为错误写法,正确格式是-lstdc++)。
正确的Makefile配置
PostgreSQL扩展的Makefile需要区分C/C文件的编译规则,同时确保链接阶段引入C标准库。修改后的配置如下:
# 指定C++编译器 CXX = g++ # C++编译选项:启用C++17标准,继承PostgreSQL的头文件与宏定义 PG_CXXFLAGS = -std=gnu++17 $(PG_CPPFLAGS) # 链接选项:强制关联C++标准库 LDFLAGS += -lstdc++ # 列出扩展所有目标文件,包含C++源文件对应的.o文件 OBJS = 你的主扩展文件.o util.o # 为C++文件添加编译规则 %.o: %.cpp $(CXX) $(PG_CXXFLAGS) -c $< -o $@ # 保留原扩展Makefile中的其他配置(如PG_CONFIG、MODULE_big等)
关键配置说明
- 编译器指定:用
g++编译C++文件,避免gcc编译带来的标准库链接缺失问题。 - 编译选项:
PG_CXXFLAGS继承PG_CPPFLAGS,确保PostgreSQL相关头文件和宏定义被正确识别,同时指定C++17标准。 - 链接选项:
LDFLAGS += -lstdc++确保链接阶段引入C++标准库,直接解决符号未定义的核心问题。 - 目标文件:将所有C++源文件对应的
.o加入OBJS列表,保证这些文件被编译并参与最终链接。
代码补充调整
你的util.cpp中输出std::string时存在格式匹配问题,elog的%s需要C风格字符串,需修改为:
elog(INFO, "string %s:", s.c_str());
PostgreSQL C++扩展开发核心规则
- 所有暴露给PostgreSQL调用的函数,必须用
extern "C"包裹,避免C++名字修饰导致的符号查找失败。 - C文件必须用C编译器编译,链接阶段必须显式关联C++标准库。
- 避免在扩展中使用未捕获的C异常,PostgreSQL的C运行时环境不处理C异常,会直接导致进程崩溃。
内容的提问来源于stack exchange,提问作者jacktan
相关产品推荐
相关产品推荐

