PostgreSQL 外部动态连接库魔法块的使用

装载:https://my.oschina.net/quanzl/blog/136907

最常见的一种方式 

CREATE FUNCTION c_overpaid(emp, integer) RETURNS boolean
    AS 'os_libpath', 'c_funcname'
    LANGUAGE C STRICT;

文档中提到两种调用习惯 V0 和 V1,从代码里边看,V0已经不再支持。
这里不去考虑函数定义方法,着重看 MAGIC 定义,相信很多朋友遇到过这个错误:

ereport(ERROR,
(errmsg("incompatible library \"%s\": missing magic block",
libname),
errhint("Extension libraries are required to use the PG_MODULE_MAGIC macro.")));


这是没有在外部库里边引入 magic data 引起的,它定义在 fmgr.h 中:

/* The actual data block contents */
#define PG_MODULE_MAGIC_DATA \
{ \
	sizeof(Pg_magic_struct), \
	PG_VERSION_NUM / 100, \
	FUNC_MAX_ARGS, \
	INDEX_MAX_KEYS, \
	NAMEDATALEN, \
	FLOAT4PASSBYVAL, \
	FLOAT8PASSBYVAL \
}

/*
 * Declare the module magic function.  It needs to be a function as the dlsym
 * in the backend is only guaranteed to work on functions, not data
 */
typedef const Pg_magic_struct *(*PGModuleMagicFunction) (void);

#define PG_MAGIC_FUNCTION_NAME Pg_magic_func
#define PG_MAGIC_FUNCTION_NAME_STRING "Pg_magic_func"

#define PG_MODULE_MAGIC \
extern PGDLLEXPORT const Pg_magic_struct *PG_MAGIC_FUNCTION_NAME(void); \
const Pg_magic_struct * \
PG_MAGIC_FUNCTION_NAME(void) \
{ \
    static const Pg_magic_struct Pg_magic_data = PG_MODULE_MAGIC_DATA; \
    return &Pg_magic_data; \
} \
extern int no_such_variable
载入外部库时,首先检查有没有 "Pg_magic_func" 函数,如果有将它的返回值与当前数据库内核定义作比较,如果不符合就会报错,具体逻辑请看 src/backend/utils/fmgr/dfmgr.c  中定义的  internal_load_library 函数  源代码。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值