Форум: "Базы";
Текущий архив: 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