Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2003.09.29;
Скачать: [xml.tar.bz2];

Вниз

User Defined Function в Interbase   Найти похожие ветки 

 
AlexPul   (2003-09-08 12:05) [0]

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

library MyUDF;

Function ANKLIKE(str1,str2 :string): Double; cdecl; export;
begin
......
end;

exports
ANKLIKE;

end.

Затем создаю саму функцию
DECLARE EXTERNAL FUNCTION ANKLIKE
VARCHAR (25),
VARCHAR (25)
RETURNS DOUBLE PRECISION BY VALUE
ENTRY_POINT "AnkLike" MODULE_NAME "MyUDF.dll";

До этого момента все отлично. Затем пытаюсь вызвать функцию в SQL и получаю ошибку:
Invalid token.
invalid request BLR at offset 60.
function ANKLIKE is not defined.
module name or entrypoint could not be found.

В чем проблема понять не могу. Я уже все перепробовал. Подскажите пожалуйста.


 
Smashich   (2003-09-08 12:08) [1]

http://www.ibase.ru/devinfo/udf_ok.htm


 
Smashich   (2003-09-08 12:09) [2]

а dll ты поместил куда надо?


 
AlexPul   (2003-09-08 12:18) [3]

>а dll ты поместил куда надо?
Да куда я уже только не пробовал.
Даже нашел настройку в ibconfig чтобы явно указать путь. Без результатов

> http://www.ibase.ru/devinfo/udf_ok.htm
Там написано ровно то же самое, что написал я выше.


 
Zacho   (2003-09-08 12:20) [4]

Обрати внимание:
exports
ANKLIKE;

но
ENTRY_POINT "AnkLike"

Имя функции - регистрозависимое, регистр должен совпадать. Т.е. правильно будет так:
ENTRY_POINT "ANKLIKE"


 
AlexPul   (2003-09-08 12:31) [5]

>Zacho
сменил, все равно не помогло.
Что самое главное, я даже стандартные функции (ABS, SIN...) не могу вызвать, хотя
DECLARE EXTERNAL FUNCTION ... отрабатывает нормально


 
Zacho   (2003-09-08 12:37) [6]


> AlexPul (08.09.03 12:31) [5]

А оно всегда нормально отрабатывает.
А commit после DECLARE .. сделал ? dll с UDF лежит в каталоге \UDF ?
Приведи свой DECLARE ... для ABS хотя бы.


 
AlexPul   (2003-09-08 12:42) [7]

>Zacho
DECLARE EXTERNAL FUNCTION ANKLIKE
VARCHAR (25),
VARCHAR (25)
RETURNS DOUBLE PRECISION BY VALUE
ENTRY_POINT "ANKLIKE" MODULE_NAME "MyUDF.dll";


 
Zacho   (2003-09-08 12:47) [8]


> AlexPul (08.09.03 12:42) [7]

Ну либо все-таки dll лежит где-то не там, либо ошибка или в имени функции, или в имени модуля, либо commit после этого не сделал. Да, еще вариант, попробуй так: ENTRY_POINT "ANKLIKE" MODULE_NAME "MyUDF";
И приведи свой нерабочий DECLARE .. для стандартной ABS из ib_udf.dll


 
AlexPul   (2003-09-08 13:00) [9]

> И приведи свой нерабочий DECLARE .. для стандартной ABS
> из ib_udf.dll
Он стандартный
DECLARE EXTERNAL FUNCTION abs
DOUBLE PRECISION
RETURNS DOUBLE PRECISION BY VALUE
ENTRY_POINT "fn_abs" MODULE_NAME "udflib";


 
Zacho   (2003-09-08 13:04) [10]


> AlexPul (08.09.03 13:00) [9]

Ну я же просил для стандартной ABS (IB_UDF_abs) из ib_udf.dll а не из некой неизвестной мне udflib.dll Да, версия IB какая ?


 
AlexPul   (2003-09-08 13:20) [11]

Firebird 1.0.3.972 for Win32


 
Zacho   (2003-09-08 13:23) [12]


> AlexPul (08.09.03 13:20) [11]

Единственное, могу еще раз повторить:
Ну либо все-таки dll лежит где-то не там, либо ошибка или в имени функции, или в имени модуля, либо commit после этого не сделал.
Других вариантов не вижу.


 
AlexPul   (2003-09-08 13:29) [13]

Я сейчас все заново проверю.
Спасибо за помощь.


 
AlexPul   (2003-09-08 17:12) [14]

Я нашел решение.
Оказывается, что в UDF НЕЛЬЗЯ передавать строки, т.е. VARCHAR (..). Нужно обязательно как PCHAR
Например
Function ANKLIKE(s1,s2: PChar; Porog: Single): Longint; cdecl; export;


 
Digitman   (2003-09-08 17:28) [15]


> AlexPul



> Оказывается, что в UDF НЕЛЬЗЯ передавать строки, т.е. VARCHAR
> (..).


да ничего подобного)
и CHAR() можно, и VARCHAR()

другой вопрос, что - верно ты подметил - любой стандартный для IB тип строковых данных д.б. объявлен в UDF DLL как PChar

в случае передачи фактического CHAR-параметра в UDF попадет PChar-указатель на первый символ параметра-строки

в случае передачи фактического VARCHAR-параметра в UDF попадет PChar-указатель не на первый символ параметра-строки, а на счетчик символов (WORD), в котором лежит размер строки. Собссно строка будет находиться по смещению +2 от адреса, который был передан как PChar


 
AlexPul   (2003-09-10 12:22) [16]

> Digitman
Не подскажешь, как правильно сделать приведение типа в самой DLL, если я передаю в качестве первого параметра значение поля таблицы VARCHAR(100), в качестве второго - STRING из SQL запроса,в качестве третьего - значение INTEGER из SQL запроса.
Т.е. запрос выглядит так:
select COUNT(*) from "Table1" where
anklike("Table1"."aaaaaaa", :SV, :PR)=1


 
Digitman   (2003-09-10 12:45) [17]


> "Table1"."aaaaaaa"


что-то мне непонятна вот эта конструкция
поясни, что это такое


 
AlexPul   (2003-09-10 12:53) [18]

Table1 - таблица
aaaaaaa - поле VARCHAR (100)


 
Digitman   (2003-09-10 13:10) [19]


> AlexPul


ясно.

какого бы типа (строкового, имеется ввиду) ни было поле "aaaaaaa", перед передачей в UDF оно будет автом-ки преобразовано сервером в тот строковый тип, который указан в DDL-декларации соотв.параметра ф-ции


 
AlexPul   (2003-09-10 13:33) [20]

Извините конечно, я уже наверное всех достал.
Я сам прекрасно все понимаю, но хоть убей не удается получить в DLL параметры функции
DECLARE EXTERNAL FUNCTION ANKLIKE
VARCHAR (100),
VARCHAR (100),
INTEGER
RETURNS INTEGER BY VALUE
ENTRY_POINT "ANKLIKE" MODULE_NAME "ankudf";

в DLL
Function ANKLIKE(s1, s2: PChar; Porog: Longint): Longint; CDECL; export;
BEGIN
ShowMessage(Format(""%s" "%s" "%d"", [s1,s2,Porog]));
END;

в результате получаю сообщение, состоящее из мусора.
если бы не специфика задачи, то проще сделать тупым фильтром, при условии малого размера таблиц...


 
Digitman   (2003-09-10 14:00) [21]

DECLARE EXTERNAL FUNCTION ANKLIKE
cstring(100),
cstring(100),
INTEGER
RETURNS INTEGER BY VALUE
ENTRY_POINT "ANKLIKE" MODULE_NAME "ankudf";

в DLL
Function ANKLIKE(s1, s2: PChar; var Porog: Longint): Longint; CDECL; export;
BEGIN
// ShowMessage(Format(""%s" "%s" "%d"", [s1,s2,Porog])); никаких ShowMessage ! Это недопустимо !
END;


 
AlexPul   (2003-09-10 14:03) [22]

Вариант с cstring(100) у меня не работает, выдается сообщение Unknown data type


 
Digitman   (2003-09-10 14:18) [23]

не выдумывай

вот выдержка из официального мануала

InterBase 6
Language Reference

strlen
Returns the length of a the input string.
DECLARE EXTERNAL FUNCTION STRLEN
CSTRING(32767)
RETURNS INTEGER BY VALUE
ENTRY_POINT ’IB_UDF_strlen’ MODULE_NAME ’ib_udf’;

как видишь, CSTRING - вполне легальный тип параметра

и с чего ты взял что сообщение об Unknown data type имеет отношение именно к CSTRING ? может у тебя запрос неверно составлен ?



Страницы: 1 вся ветка

Форум: "Базы";
Текущий архив: 2003.09.29;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.49 MB
Время: 0.008 c
1-96164
k2
2003-09-16 10:21
2003.09.29
Приведение типов


1-96240
vlv
2003-09-17 16:28
2003.09.29
Можно ли с помощью TRegistry работать с удаленным реестром?


3-96066
vopros
2003-09-10 12:18
2003.09.29
У DbgridEh Можно ширину колонки менять


1-96171
servs
2003-09-15 18:33
2003.09.29
проблемы с СОМ под 9х


14-96368
Freeek
2003-09-11 18:01
2003.09.29
День рождение





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский