UDF не работает в процедуре и триггере

ЧАстые Вопросы и Ответы

Модераторы: kdv, CyberMax

Ответить
KWladimir
Сообщения: 15
Зарегистрирован: 29 ноя 2006, 16:13

UDF не работает в процедуре и триггере

Сообщение KWladimir » 31 янв 2007, 13:28

Взята библиотека CaseUDF (http://www.ibase.ru/download/caseudf.zip).
В неё добавлена примитивная функция - "всю строку сделать нижней, первый символ - верхним":

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

function Proper(s: String): PChar; cdecl; export;
var
  n: Integer;
begin
s := AnsiLowerCase(s);
n := Length(s);

if (n>0) then
  s[1] := AnsiUperCase(s[1])[1];

Result := ib_util_malloc(n + 1);  // сначала было malloc из msvcrt.dll
StrPCopy(Result, s);

end;
В базе объявлена как:
DECLARE EXTERNAL FUNCTION PROPER
CSTRING(255)
RETURNS CSTRING(255) FREE_IT
ENTRY_POINT 'Proper' MODULE_NAME 'udfunx.dll'


При отладке в IB Expert / SQL редактор:

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

select PROPER('йЦукен') from RDB$DATABASE;
работает нормально - возвращает 'Йцукен'

Но если это же помещаю в простейшую ХП (с FOR вот-это-самое INTO параметр) или триггер -
возвращает или случайный текст, или пустую строку (т.е. видимо в любом случае - какой-то случайный буфер).

Никак не могу найти, что здесь не так.

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

Сообщение kdv » 31 янв 2007, 13:40

отладчиком. или сделать как в www.ibase.ru/download/safeudf.zip

я понимаю, что caseudf это мое, но это старье, и пока переделывать или тестить его нет времени, извиняюсь.

KWladimir
Сообщения: 15
Зарегистрирован: 29 ноя 2006, 16:13

Сообщение KWladimir » 31 янв 2007, 14:09

Да, понял, спасибо.
Сделал через запись в исходный буфер, без маллока.

P.S.
У знакомого также заработало, когда он вместо Length(sSource) подставил
n := 0;
while (s[n] <> #0) do
Inc(n);
Inc(n);

Dimitry Sibiryakov
Заслуженный разработчик
Сообщения: 1436
Зарегистрирован: 15 сен 2005, 09:05

Сообщение Dimitry Sibiryakov » 31 янв 2007, 14:19

Заработало? Даже с этим: (s: String) ??? Везунчики, блин...

KWladimir
Сообщения: 15
Зарегистрирован: 29 ноя 2006, 16:13

Сообщение KWladimir » 31 янв 2007, 14:25

Ещё он вместо цикла (и Length) подставил StrLen - тоже пока работает.

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

Сообщение kdv » 31 янв 2007, 14:47

тьфу, блин. конечно там не должно быть string.
автор топика! Какого фига мои функции корежите!!!

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

KWladimir
Сообщения: 15
Зарегистрирован: 29 ноя 2006, 16:13

Сообщение KWladimir » 31 янв 2007, 15:17

мои функции корежите!
Ваши, кстати, не корёжил. Просто взял dpr за основу.
Саму функцию брал из других примеров.
накой фиг там free_it вам потребовался
Так внутри же malloc вызывается.

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

Сообщение kdv » 31 янв 2007, 15:27

Саму функцию брал из других примеров.
из каких? на сайте не должно быть примеров, где
передача строки в udf идет как string. Это известно
уже минимум 10 лет.
Так внутри же malloc вызывается.
где? Если Вы смотрели caseudf, то там написано:
"если вам потребуется..."
при этом НИ В ОДНОЙ функции free_it не используется. Сравните Ваш вариант и мой исходный:

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

{ DECLARE EXTERNAL FUNCTION UPCASE
   CSTRING(255) RETURNS CSTRING(255)
  ENTRY_POINT 'UpCase'  MODULE_NAME 'CASEUDF' }

function UpCase(CStr: PChar): PChar; cdecl; export;
 begin
  CharUpperBuff(CStr, Length(CStr));
  Result:=CStr;
 end;
можно ведь было поменять как надо, и все.

Ответить