|
Программирование >> Oracle
Внешние процедуры на языке С 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-библиотеку. Она скомпилирует и скомпонует весь необходимый код.
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |