Программирование >>  Oracle 

1 ... 302 303 304 [ 305 ] 306 307 308 ... 469


Внешние процедуры на языке С 1329

raise application error(myCtx, ERROR OCI ERROR, %s ,

не хватает памяти ) ;

else

*return i = OCI IND NULL;

if (OCIDateSysDate(myCtx->errhp, return value) != OCI SUCCESS)

raise application error(myCtx,ERROR OCI ERROR,

%s ,lastOciError(myCtx));

*return i = OCI IND NOTNOLL;

term(myCtx);

return return value;

При возврате строковых данных (VARCHAR) будут использоваться два параметра: индикаторная переменная и поле LENGTH. В этом случае, как и для параметра, переданного в режиме OUT, задается поле LENGTH, чтобы в вызывающей среде была известна длина возвращенной строки.

Представленные выше соображения во многом применимы и при возврате строк: выделяется память, устанавливается индикаторная переменная, задается и возвращается значение:

#ifdef WIN

declspec (dllexport) #endif

char * returnstring

(OCIExtProcContext * ctx,

short * return i,

int * return l)

char * data we want to return - Hello World! ;

char * return value; myCtxStruct*myCtx;

if ((myCtx = init(ctx)) - NOLL) return NULL;

debugf(myCtx, Вход в функцию, возвращающую строку ) ;

return value = (char *)OCIExtProcAllocCallMemory(ctx,

strlen(data we want to return)+1);

if(return value = NULL)

raise application error(myCtx, ERROR OCI ERROR, %s ,

не хватает памяти ) ;

else

*return i = OCI IND NULL;

strcpy(return value, data we want to return); *return l = strlen(return value);



1330

Глава 18

*return i = OCI IND NOTNULL;

term(myCtx);

return return value;

Мы рассмотрели код на языке С, необходимый для демонстрации способов передачи всех основных типов данных в режиме IN и IN/OUT, а также возврата данных соответствующих типов из функций. Было представлено также множество функций био-теки OCI, использующихся во внешних процедурах, в частности функции для создания и получения контекста с целью поддержки информации о состоянии, функции для обработки файлов параметров, создания и записи файлов ОС. Не продемонстрировано следующее.

Передача и получение данных сложн1х объектных типов во внешних проду-рах. Делается это примерно так же, как и в примерах с массивами (посколькутам передавались и принимались данные простых объектных типов). Для работы с входными и выходными данными объектных типов используются предоставляемые библиотекой OCI средства работы с компонентами объекта.

Возврат всех необходимтх типов из функций. Я представил только возврат строк, дат и чисел. Возврат данных остальных типов выполняется аналогично (несколько проще для данных типа int, поскольку при этом не надо выделять память).

Сейчас мы рассмотрим файлы управления проектом, make-файлы, которые мож использоватьдля создания внешних процедур в среде ОС UNIX или Windows.

Создание внешней процедуры

Давайте сначала рассмотрим универсальный make-файл для Windows:

CPU=i386

MSDEV = c:\msdev

ORACLE HOME = c:\oracle

!include <$(MSDEV)\include\win32.mak>

TGTDLL = extproc.dll = extproc.obj

OBJS

NTUSER32LIBS

SQLLIB

INCLS

= $(MSDEV)\lib\user32.1ib $(MSDEV)\lib\msvcrt.lib \ $(MSDEV)\lib\oldnames.lib \ $(MSDEV)\lib\kernel32.1ib \ $(MSDEV)\lib\advapi32.lib

$(ORACLE HOME)\precomp\lib\msvc\orasql8.1ib $(ORACLE HOME)\oci\lib\msvc\oci.lib

-I$(MSDEV)\include \ -I$(ORACLE HOME)\oci\include \

(3) (4)

(5 ) (6 )

CFLAGS

$(INCLS) -DWIN32 -DWIN NT -D DLL



Внешние процедуры на языке С 1331 all: $(TGTDLL) (10)

clean: (11)

erase *.obj *.lib *.exp

$(TGTDLL): $(OBJS) (12)

$(link) -D $(dllflags) \

/NODEFAULTLIB:LIBC.LIB -out:$(TGTDLL) \ $(0BJS) \ $(NTUSER32LIBS) \ $(SQLLIB)

Выделенные полужирным числа в круглых скобках не являются частью файла управления проектом, ониуказанылишь для возможности ссылкина нихв дальнейшем.

1. Это каталог, в котором у меня установлен компилятор языка С. Я использую компилятор Microsoft Visual C/C+ + , который поддерживается в среде Windows. Значение этой переменной я использую позже в make-файле, когда необходимо сослаться на этот каталог.

2. Мой каталог ORACLE HOME. Он используется при поиске включаемых файлов для ОСI/Pro*С и стандартных библиотек Oracle.

3. Я включаю стандартный шаблон make-файла Microsoft. Он задает переменные $(link) и $(dllflags), которые могут быть разными для различных версий компилятора.

4. Переменная TGTDLL задает имя создаваемой DLL-библиотеки.

5. Переменная OBJS задает список объектных файлов, используемых при создании библиотеки. Если распределить код по нескольким файлам, в списке будет указано несколько объектных файлов. В нашем несложном примере используется только один объектный файл.

6. Переменная NTUSER32LIBS содержит список стандартных системных библиотек, с которыми выполняется компоновка.

7. Переменная SQLLIB содержит список необходимых библиотек Oracle. В данном примере я компоную библиотеки как Pro*С, так и OCI, хотя используются только библиотеки OCI. Но от включения библиотек Pro*С вреда не будет.

8. Переменная INCLS содержит список каталогов, в которых находятся необходимые включаемые файлы. В данном случае мне необходимы системные заголовочные файлы, а также заголовочные файлы сервера Oracle и текущий рабочий каталог.

9. Переменная CFLAGS - стандартный макрос языка С, используемый компилятором. Я определяю макрос -DWIN NT, для условной компиляции кода, предназначенного для NT (например, declspec(dllexport)).

10. Цель all: по умолчанию будет создавать DLL-библиотеку.

11. Цель clean: требует удалить временные файлы, созданные в ходе компиляции.

12. Цель TGTDLL требует выполнить команду, создающую DLL-библиотеку. Она скомпилирует и скомпонует весь необходимый код.



1 ... 302 303 304 [ 305 ] 306 307 308 ... 469

© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика