参考ORACLE调用外部库的google上的技术要点:
http://docs.oracle.com/cd/B12037_01/appdev.101/b10795/adfns_ex.htm
LINUX下通过ORACLE的extproc调用外部由BASE64编写的C动态链接库。
1)编译出外部动态库libbase64.so
这里只支持用C写的编译库,C++的编译方式需要自己研究
base64.c代码如下:


1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 static const char basis_64[] = 6 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 7 8 static const unsigned char pr2six[256] = 9 { 10 /* ASCII table */ 11 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 12 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 13 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63, 14 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64, 15 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64, 17 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 18 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64, 19 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 20 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 21 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 22 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 23 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 24 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 25 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 26 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 27 }; 28 29 int EncodeLen(int len) 30 { 31 return ((len + 2) / 3 * 4) + 1; 32 } 33 34 int Base64Encode(char *encoded, const char *string, int len) 35 { 36 int i; 37 char *p; 38 39 p = encoded; 40 for (i = 0; i < len - 2; i += 3) { 41 *p++ = basis_64[(string[i] >> 2) & 0x3F]; 42 *p++ = basis_64[((string[i] & 0x3) << 4) | 43 ((int) (string[i + 1] & 0xF0) >> 4)]; 44 *p++ = basis_64[((string[i + 1] & 0xF) << 2) | 45 ((int) (string[i + 2] & 0xC0) >> 6)]; 46 *p++ = basis_64[string[i + 2] & 0x3F]; 47 } 48 if (i < len) { 49 *p++ = basis_64[(string[i] >> 2) & 0x3F]; 50 if (i == (len - 1)) { 51 *p++ = basis_64[((string[i] & 0x3) << 4)]; 52 *p++ = '='; 53 } 54 else { 55 *p++ = basis_64[((string[i] & 0x3) << 4) | 56 ((int) (string[i + 1] & 0xF0) >> 4)]; 57 *p++ = basis_64[((string[i + 1] & 0xF) << 2)]; 58 } 59 *p++ = '='; 60 } 61 62 *p++ = '\0'; 63 return p - encoded; 64 } 65 66 67 int DecodeLen(const char *bufcoded) 68 { 69 int nbytesdecoded; 70 register const unsigned char *bufin; 71 register int nprbytes; 72 73 bufin = (const unsigned char *) bufcoded; 74 while (pr2six[*(bufin++)] <= 63); 75 76 nprbytes = (bufin - (const unsigned char *) bufcoded) - 1; 77 int nCover = strlen(bufcoded) - nprbytes; 78 nbytesdecoded = ((nprbytes + 3) / 4) * 3; 79 80 return nbytesdecoded - nCover; 81 } 82 83 int Base64Decode(char *bufplain, 84 const char *bufcoded) 85 { 86 int nbytesdecoded; 87 register const unsigned char *bufin; 88 register unsigned char *bufout; 89 register int nprbytes; 90 91 bufin = (const unsigned char *) bufcoded; 92 while (pr2six[*(bufin++)] <= 63); 93 nprbytes = (bufin - (const unsigned char *) bufcoded) - 1; 94 nbytesdecoded = ((nprbytes + 3) / 4) * 3; 95 96 bufout = (unsigned char *) bufplain; 97 bufin = (const unsigned char *) bufcoded; 98 99 while (nprbytes > 4) { 100 *(bufout++) = 101 (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4); 102 *(bufout++) = 103 (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2); 104 *(bufout++) = 105 (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]); 106 bufin += 4; 107 nprbytes -= 4; 108 } 109 110 /* Note: (nprbytes == 1) would be an error, so just ingore that case */ 111 if (nprbytes > 1) { 112 *(bufout++) = 113 (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4); 114 } 115 if (nprbytes > 2) { 116 *(bufout++) = 117 (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2); 118 } 119 if (nprbytes > 3) { 120 *(bufout++) = 121 (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]); 122 } 123 124 nbytesdecoded -= (4 - nprbytes) & 3; 125 return nbytesdecoded; 126 }
编译成libbase.so,编译命令:
gcc -fPIC -c base64.c
ld -shared -o libbase64.so base64.o
2)oracle方面修改(服务器上)
listener.ora
SID_LIST_LISTENER=
(SID_LIST=
(SID_DESC=
(SID_NAME = PLSExtProc)
(ORACLE_HOME = /oraapp/oracle/productt/11.2.0/dbhome_1)
(ENVS = EXTPROC_DLLS=ANY)
(PROGRAM = extproc)
)
)
tnsnames.ora
EXTPROC_CONNECTION_DATA=
(DESCRIPTION=
(ADDRESS_LIST=
(ADDRESS = (PROTOCOL = IPC)(KEY=EXTPROC))
)
(CONNECT_DATA=
(SID = PLSExtProc)
(PRESENTATION=RO)
)
)
修改完成后重启监听:lsnrctl stop;lsnrctl start
3)进入SQLPLUS连接到数据库
SQL>create library libbase as '/tmp/libbase64.so';
2 /
Library created.
SQL>create or replace function encodelen(len int binary_integer) return binary_integer
AS EXTERNAL name "EncodeLen"
library libbase
LANGUAGE C
PARAMETERS(len int);
/
Function created.
SQL>select encodelen(1) from dual; (或者select encodelen(tablename.字段名) from tablename)
ENCODELEN(1)
----------------------
5
有返回值,说明调用完成。
每个函数都需要创建一次。