创建OCI环境
在编写OCI程序的第一步就是创建OCI环境,然后分配需要的句柄,下面介绍创建OCI环境的函数。这是OCI程序第一个要调用的函数,名字叫做OCIEnvCreate()。看一下它的函数原型和参数。
sword OCIEnvCreate ( OCIEnv **envhpp,
ub4 mode,
const void *ctxp,
const void *(*malocfp)(void *ctxp, size_t size),
const void *(*ralocfp)(void *ctxp, void *memptr, size_t newsize),
const void (*mfreefp)(void *ctxp, void *memptr),
size_t xtramemsz,
void **usrmempp );
envhpp是一个输出参数,是一个指针的指针,为了要把创建的环境句柄带回来。后面的函数会用到这个句柄。
mode是一个输入参数,指示创建OCI环境的模式。有几个主要的模式介绍一下,一般用到的是缺省模式OCI_DEFAULT,大部分程序用这个模式就够了。如果使用多线程调用OCI函数,那么就要用到线程模式OCI_THREADED,这样可以保证每个线程都有一份环境内存,不相互干扰,否则线程之间互相修改共享的环境内存,会造成coredump。如果使用OCI中的对象操作函数,就要用到OCI_OBJECT模式。
ctxp是一个输入参数,指示用户定义的上下文指针,给回调函数用的,一般赋值为NULL就可以了。
malocfp是一个输入参数,是一个函数指针,是用户定义的分配内存的函数,类似C语言中的malloc()函数,一般赋值为NULL。
ralocfp是一个输入参数,是一个函数指针,是用户定义的再分配内存的函数,类似C语言中的realloc()函数,一般赋值为NULL。
mfreefp是一个输入参数,是一个函数指针,是用户定义的释放内存的函数,类似C语言中的free()函数,一般赋值为NULL。由于创建OCI环境变量需要分配一定大小的内存,分配过程中就会用到内存分配函数,上面的三个函数指针就是为分配内存和释放内存准备的,让用户可以自己分配和释放内存,如果没有用户自己定义的函数,那么都赋值为NULL,创建OCI环境时就使用系统自己的分配和释放内存的函数。
xtramemsz是一个输入参数,指示额外分配内存的大小,这个内存可以给用户使用,生命周期与OCI环境的生存期一样长,在释放环境内存时才一起释放掉。一般不用这个内存,可以赋值为0。
usrmempp是一个输出参数,带回分配的用户内存的指针。这个参数与上一个参数是相关的,如果上一个参数大于0,那么必须赋值把分配的用户内存指针带回来,如果上个参数为0,这里赋值为NULL就可以了。
OCIEnvNlsCreate()的返回值是一个sword类型的整数,实际上就是一个有符号的整数。所有的OCI函数返回值都是sword整数,绝大多数的时候返回值是OCI_SUCCESS或OCI_ERROR,表示函数执行成功或出错,特定的函数还会返回其他值,后面遇到时再介绍。
看一个实际的例子。
OCIEnv *envhp = NULL;
sword rc;
rc = OCIEnvCreate(
&envhp, /* envhpp */
OCI_DEFAULT, /* mode */
(void *)NULL, /* ctxp */
NULL,
NULL,
NULL,
(size_t)0,
(void **)NULL
);
if (rc != OCI_SUCCESS) {
fprintf(stderr, "OCIEnvCreate() - allocate OCI env handle error !\n");
return (-1);
}
这里返回的envhp就是创建的OCI环境变量指针。
分配句柄
创建完OCI环境之后,马上就要分配必须的句柄才能连接到数据库,分配句柄的函数叫做OCIHandleAlloc()。看一下它的原型和参数。
sword OCIHandleAlloc ( const void *parenth,
void **hndlpp,
ub4 type,
size_t xtramem_sz,
void **usrmempp );
parenth是一个输入参数,表示被分配句柄的父句柄指针,一般会是OCI环境句柄。
hndlpp是一个输出参数,带回被分配的句柄指针。
type是一个输入参数,指示分配句柄的类型。句柄类型有很多,在后面用到时再一一介绍。
xtramem_sz是输入参数,指示额外分配的跟句柄关联的用户内存大小,与创建OCI环境函数的最后两个参数意义相同。不想分配的话赋值为0。
usrmempp是输出参数,带回分配的用户内存的指针。
一个实际的例子,在创建OCI环境后,第一个要分配的句柄就是处理错误的句柄,类型为OCI_HTYPE_ERROR,我们来看一下。
sword rc;
rc = OCIHandleAlloc(
(const void *)envhp,
(void **)&errhp,
OCI_HTYPE_ERROR,
0,
(void **)NULL
);
if (rc != OCI_SUCCESS) {
fprintf(stderr, "OCIHandleAlloc() - allocate OCI error handle error !\n");
return (-1);
}
下一节我们再来看看还要分配哪些句柄,怎样连接到数据库。