文件pf.c内容如下:
#include "postgres.h"PG_MODULE_MAGIC;intadd_one(int arg){ return arg + 1;}
编译:
gcc -I../../src/postgresql-9.0.3/src/include -c pf.cgcc -shared -o pf.so pf.o
把编译生成的pf.so文件拷贝到PostgreSQL的库目录下:
cp pf.so ~/local/pgsql/lib
到postgresql中:
osdba@osdba-laptop:~$ psqlpsql (9.0.3)Type "help" for help.
osdba=# load 'pf.so';ERROR: incompatible library "/home/osdba/local/pgsql9.0.3/lib/pf.so": missing magic blockHINT: Extension libraries are required to use the PG_MODULE_MAGIC macro.STATEMENT: load 'pf.so';ERROR: incompatible library "/home/osdba/local/pgsql9.0.3/lib/pf.so": missing magic blockHINT: Extension libraries are required to use the PG_MODULE_MAGIC macro.
报错,提示需要magic block,在pf.c中加宏PG_MODULE_MAGIC:#include "postgres.h"PG_MODULE_MAGIC;intadd_one(int arg){ return arg + 1;}
然后再编译后还是报“missing magic block”错。
文件中增加头文件#include "fmgr.h",源文件内容如下:#include "postgres.h"#include "fmgr.h"PG_MODULE_MAGIC;/* 传递数值 */ intadd_one(int arg){ return arg + 1;}
再编译:
osdba@osdba-laptop:~/03.tangsrc/pgtest$ gcc -I../../src/postgresql-9.0.3/src/include -c pf.cosdba@osdba-laptop:~/03.tangsrc/pgtest$ gcc -shared -o pf.so pf.o/usr/bin/ld: pf.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPICpf.o: could not read symbols: Bad valuecollect2: ld returned 1 exit status编译报错,加编译选项-fpic,编译通过:
osdba@osdba-laptop:~/03.tangsrc/pgtest$ gcc -fpic -I../../src/postgresql-9.0.3/src/include -c pf.cosdba@osdba-laptop:~/03.tangsrc/pgtest$ gcc -fpic -shared -o pf.so pf.o
现在就成功了:
osdba=# load 'pf.so';LOAD
osdba=# CREATE FUNCTION add_one(integer) RETURNS integer AS '$libdir/pf', 'add_one' LANGUAGE C STRICT;CREATE FUNCTIONosdba=# select add_one(10); add_one --------- 11(1 row)
总结一下:
1. 程序中的源代码中要加宏PG_MODULE_MAGIC;
2. 程序中要加#include "fmgr.h"
3. 编译时要加-fpic选项。
如果没有注意到以上三点,load动态库时,都可能报“missing magic block”错误。