простенькая UDF на FreePascal

IBX, FIBPlus, UIB, ADO, .Net и прочее-прочее-прочее, в общем все, что относится к созданию приложений, работающих с InterBase, Firebird и Yaffil - клиент-серверных, трехзвенных, консольных и т.п.

Модератор: kdv

Ответить
aaa3d
Сообщения: 69
Зарегистрирован: 23 ноя 2005, 11:06

простенькая UDF на FreePascal

Сообщение aaa3d » 17 авг 2006, 10:08

переношу базу на Linux. от старых времен имеется 2 десятка UDF функций для
работы со строками, числами и датами. Изначально были написаны на Delphi.

MandrivaLinux 2006. Firebird SS 1.5.3

Сейчас скомпилировал на FreePascal под Linux. половина работает половина нет :(
конечно, самый разумный совет наверно - предложить все переписать на С - но я его подзабыл :)
Может, есть другой способ решения проблемы?

симптом тех функций которые не работают - соединение повисает полностью.

bg_fixedpoint - вешает
bg_dayofweek - спокойно работает

самое противное - все функции правильные - при запуске в проекте отрабатывают нормально. а при вызове их как UDF - вешают соединение

код библиотечки - слегка покоцаный
lbrary bg_udf;
uses SysUtils;

Код: Выделить всё

function bg_fixedpoint(var a:double;var b:integer):double; cdecl; export;
begin
   result:=strtofloat(floattostrf(a,fffixed,20,b));
end;
function bg_dayofweek(var d:tm):integer; cdecl; export;
begin
  result:=dayofweek(encodedate(1858,11,17)+d.a+d.b/864000000);
end;


initialization
  IsMultiThread:=True
end.
exports
bg_fixedpoint,
bg_dayofweek;

DECLARE EXTERNAL FUNCTION BG_FIXEDPOINT
Double precision, Integer
RETURNS Double precision BY VALUE
ENTRY_POINT 'bg_fixedpoint'
MODULE_NAME 'bg_udf.dll';

DECLARE EXTERNAL FUNCTION BG_DAYOFWEEK
Timestamp
RETURNS Integer BY VALUE
ENTRY_POINT 'bg_dayofweek'
MODULE_NAME 'bg_udf.dll';

module_name - в порядке. компилирую библиотечку libbg_udf.dll.so - Firebird ее цепляет как надо.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 17 авг 2006, 11:52

симптом тех функций которые не работают - соединение повисает полностью.
увы, это FreePascal. функции действительно лучше переписать на C/C++. Или найти аналоги в rfunc (или по образу и подобию сделать).

DSKalugin
Сообщения: 212
Зарегистрирован: 27 окт 2004, 13:39

Сообщение DSKalugin » 19 сен 2006, 13:18

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

SSY
Сообщения: 11
Зарегистрирован: 27 окт 2004, 14:27

Сообщение SSY » 17 окт 2006, 15:29

kdv писал(а):
симптом тех функций которые не работают - соединение повисает полностью.
увы, это FreePascal. функции действительно лучше переписать на C/C++. Или найти аналоги в rfunc (или по образу и подобию сделать).
В общем и целом Дмитрий прав, но, скорее всего, можно решить проблему оставаясь на FreePascal. См. тут

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 17 окт 2006, 15:50

ссылка интересная, но когда внутри udf выделяют память - серверу без разницы. Если бы речь шла про free_it, то тоже без вопросов - память выделяется ib_util_malloc.
В первом письме топика я не вижу где тут может аллокироваться память. Вот если бы кто разобрался, почему udf на freepascal частенько валят сервер...

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 17 окт 2006, 18:48

kdv писал(а):Вот если бы кто разобрался, почему udf на freepascal частенько валят сервер...
Фрипаскаль, фрипаскаль... Я вот сегодня с пятой дельфой секс имел по полной. Пока раскопал, что замечательная функция Int() не только выдаёт результат в Int64, но и, на всякий случай видимо, "округляет" аргумент. Типа пятничный прикол от Борланд.

SSY
Сообщения: 11
Зарегистрирован: 27 окт 2004, 14:27

Сообщение SSY » 17 окт 2006, 22:35

kdv писал(а):ссылка интересная, но когда внутри udf выделяют память - серверу без разницы. Если бы речь шла про free_it, то тоже без вопросов - память выделяется ib_util_malloc.
В первом письме топика я не вижу где тут может аллокироваться память. Вот если бы кто разобрался, почему udf на freepascal частенько валят сервер...
Память может выделяться не совсем явно и не прямо в самой udf. Например, там используется весьма нетривиальная функция FloatToStrF, за поведение которой ручаться, ИМХО, сложно. И, разумеется, дело может быть и не в распределении памяти.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 17 окт 2006, 23:20

Например, там используется весьма нетривиальная функция FloatToStrF
а пофиг. я в функции могу и getmem сделать. главное чтобы я это не скормил серверу как выходной free_it-параметр.
И, разумеется, дело может быть и не в распределении памяти.
скорее всего.

Мансур
Сообщения: 6
Зарегистрирован: 05 июл 2006, 18:07

Re: простенькая UDF на FreePascal

Сообщение Мансур » 07 ноя 2006, 13:48

aaa3d писал(а):переношу базу на Linux. от старых времен имеется 2 десятка UDF функций для
работы со строками, числами и датами. Изначально были написаны на Delphi.
Сам натыкался на такие грабли: http://www.sql.ru/forum/actualthread.aspx?tid=311502. В FAQ по FP сказано, что текущая версия FP не поддерживает "position independant code (PIC)" для *NIX. Т.е. библиотека компилится, загружается, но заработает она или нет, видимо зависит от того, загрузится она по тому адресу, на который рассчитана или нет (сразу оговорюсь, я в принципах работы линуксовых библиотек и загрузчика не копенгаген, мог ошибиться в деталях). Вывод напрашивается такой: лучше переписать на C либо поискать разновидность компилятора Паскаля, которая поддерживает создание корректных DLL(so) для Linux.

Ответить