使用C語言寫PostgreSQL函式

2021-07-10 16:25:53 字數 3504 閱讀 8626

使用c語言寫postgresql中的函式可以很方便的擴充套件postgresql資料庫的功能。由c語言寫的函式,使用方法與postgresql中內建的函式基本沒有差別,效能基本也沒有什麼差別。本文一步一步教你如何使用c語言寫postgresql函式:

原始檔為cfunc.c,內容如下:

#include "postgres.h"

int add_one(int arg)

然後我們編譯生成cfunc.so,並把此檔案拷貝到postgresql的庫路徑下:

gcc -i`pg_config --includedir-server` -c cfunc.c

gcc -shared -o cfunc.so cfunc.o

cp cfunc.so `pg_config --libdir`/.

我們來測試一下:

osdba@osdba-laptop:~/src/ctest/pgfunc$ psql

psql (9.3.2)

type "help" for help.

osdba=# load

'cfunc.so';

error: incompatible library "/home/osdba/pgsql9.3.2/lib/cfunc.so": missing magic block

hint: extension libraries are required to use the pg_module_magic macro.

發現報「missing magic block」的錯誤。那麼什麼是「magic block」呢? postgresql使用的動態庫中要求打上乙個特殊的標記,當postgresql裝載這個動態庫時,會檢查這個標記,如果沒有發現這個標記或發現這個標記與需求的標記不同(如版本不對上)則會報上面這個錯誤。

那麼如何在動態庫中增加這個「magic block」標記呢?方法是在源**中加下面兩行:

#include "postgres.h"

#include "fmgr.h"

#ifdef pg_module_magic

pg_module_magic;

#endif

這樣之後,我們的源**最終如下:

#include "postgres.h"

#include "fmgr.h"

#ifdef pg_module_magic

pg_module_magic;

#endif

int add_one(int arg)

再編譯一下:

osdba@osdba-laptop:~/src/ctest

/pgfunc$ gcc -i`pg_config --includedir-server` -c cfunc.c

osdba@osdba-laptop:~/src

/ctest/pgfunc$ gcc -shared -o cfunc.so cfunc.o

/usr/bin/ld: cfunc.o: relocation r_x86_64_32 against `.rodata' can not be used when ****** a shared object; recompile with -fpic

cfunc.o: error adding symbols: bad value

collect2: error: ld returned 1 exit status

根據報錯資訊,我們知道在編譯時,需要加「-fpic」的引數,再重試一下:

osdba@osdba-laptop:~/src/ctest/pgfunc$ gcc -i`pg_config --includedir-server` -fpic  -c cfunc.c

osdba@osdba-laptop:~/src/ctest/pgfunc$ gcc -shared -o cfunc.so cfunc.o

osdba@osdba-laptop:~/src/ctest/pgfunc$ cp cfunc.so `pg_config --libdir`/.

編譯通過,我們再重試一下:

osdba@osdba-laptop:~/src/ctest/pgfunc$ psql

psql (9.3

.2)type "help"

for help.

osdba=# load 'cfunc.so';

load

osdba=#

裝載成功了,我們來使用一下這個動態庫,使用之前需要先建立addone函式,建立語句如下:

create

function add_one(integer) returns integer

as'$libdir/cfunc1', 'add_one'

language c strict;

執**況如下:

osdba=# create

function add_one(integer) returns integer

as'$libdir/cfunc', 'add_one'

language c strict;

create

function

osdba=#

建立成功了,使用一下:

osdba=# select

add_one(1);

add_one

---------

2(1 row)

osdba=# select

add_one(23);

add_one

---------

24(1 row)

總結一下:

程式中的源**中要加巨集pg_module_magic;

程式中要加#include "fmgr.h"

編譯時要加-fpic選項。

如果沒有注意到以上三點,load動態庫時,都可能報「missing magic block」錯誤。

實際上面描述的是乙個最簡單的使用c語言寫postgresql函式的方法。為了讓寫出來函式能更好的與資料庫之間互動,postgresql搞了乙個更高階的呼叫規則,前面的方法為「version 0 calling conventions」,更高階的呼叫規則稱之為「version 1 calling conventions」,這個呼叫規則下,函式的宣告都有統一的如下形式:

datum funcname(pg_function_args)
同時為了告訴postgresql使用的是版本1的呼叫規則,需要加函式:

pg_function_info_v1(funcname);
具體的使用方法見 postgresql官方檔案 ,我在這裡只做拋磚引玉。

使用perl連線和操作postgresql資料庫

使用環境 linux opensuse 1 檢查安裝環境 1 查詢dbi zypper search dbi 安裝dbi zypper search perl dbi 2 查詢dbd pg zypper search dbd 安裝dbd pg zypper install perl dbd pg 2...

C語言寫日曆

include 1970 1 1 星期四 以1970 1 1作為基準 int start year 1970 int start month 1 int start day 1 將以char輸進來的字串轉換成int型,並完成錯誤檢查和資訊篩選 int char to int char s,int s...

C語言寫檔案

一 fopen 函式 fopen 函式宣告在stdio.h標頭檔案,第乙個引數開啟包含該檔名的字串的位址,第二個引數是用於指定檔案開啟模式的乙個字串。二 getc 和putc 函式 ch get fp 從指標fp指定的檔案中會的乙個字元。putc ch,fp 將字元寫到fp 指定的檔案中。三 fcl...