![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
UDF [D7, XP]
Irish_34 © (2007-12-10 20:02:00)Привет ВСЕМ, помогите пожалусто UDF, начиная работать в процедуре "спотыкается" об чего, я уже не знаю в чем и ошибка и чге я некоректно что обозвала
DECLARE EXTERNAL FUNCTION CEX6
VARCHAR(50)
RETURNS VARCHAR(50) BY DESCRIPTOR
ENTRY_POINT 'psc6' MODULE_NAME 'PDL6.dll'
function psc6(var s:PChar):PChar;cdecl;export;
var
j1,i1:byte;
j: PSmallInt;
s1: string;
begin
j:=nil;
j1:=0;
i1:=0;
if ((s=nil) or (s='0') or (s='')) then
Result:='0'
else
if StrPos(s,'6')<>nil then
begin
j:=PSmallInt(StrPos(s,'6'));
s1:=PChar(s)^;
Result:='';
delete(s1,1,j^+1);
if Length(s1)=1 then //s:=copy(s1,1,1)
StrPLcopy(Result,s1,1)
else
begin
for i1:=1 to length(s1) do
if ((s1[i1]=',') or (s1[i1]='.') or (s1[i1]=';') or (s1[i1]=' '))
then
begin
delete(s1,i1,length(s1));
StrPLcopy(Result,s1,length(s1));
end
else StrPLcopy(Result,s1,2);
end;
end
else
Result:='';
end;
Сергей М. (2007-12-15 13:32:00) [61]
> для работы со строками
Это из другой оперы.
Убирай.
> на работу никак не влияет
>
Влияет. Не лучшим образом. Просто ты этого не ощущаешь.
irish_34 (2007-12-15 13:22:00) [62]
> Это еще зачем ?
для работы со строками, но на работу никак не влияет
Сергей М. (2007-12-15 12:45:00) [63]
> uses ShareMem
Это еще зачем ?
irish_34 (2007-12-15 11:18:00) [64]кстати заработала она не от "result:=malloc(6); result[6]:=#0;", а от того что я удалила цикл и удалила перебор символов строки (s[i])
irish_34 (2007-12-15 11:16:00) [65]
> ПРиводи полный текст своей udf dll
{.$Define Debug}
{$ALIGN OFF}
unit UDFL6;
interface
uses ShareMem, SysUtils;
implementation
function malloc(Size:integer):PChar;cdecl;external 'msvcrt.dll';
function psc6(s:PChar):PChar;cdecl;export;
var
i1,j,j1:byte;
s1: string;
begin
j1:=0;
result:=malloc(6);
if (s=nil) then s1:='0'
else
begin
s1:=string(s);
if Pos('6',s1)>0 then
begin
delete(s1,1,Pos('6',s1));
if Pos(',',s1)>0 then j1:=Pos(',',s1) else
if Pos('.',s1)>0 then j1:=Pos('.',s1) else
if Pos(';',s1)>0 then j1:=Pos(';',s1) else
if Pos(' ',s1)>0 then j1:=Pos(' ',s1) else
if Pos(')',s1)>0 then j1:=Pos(')',s1);
if j1>0 then delete(s1,1,j1) else s1:='0';
if length(s1)=0 then s1:='0' else
begin
j:=0;
if Pos(',',s1)>0 then delete(s1,Pos(',',s1),length(s1));
if Pos('.',s1)>0 then delete(s1,Pos('.',s1),length(s1));
if Pos(';',s1)>0 then delete(s1,Pos(';',s1),length(s1));
if Pos(' ',s1)>0 then delete(s1,Pos(' ',s1),length(s1));
end;
end
else s1:='0';
end;
StrPcopy(result,s1);
result[6]:=#0;
end;
exports
psc6;
end.
irish_34 (2007-12-15 11:16:00) [66]
> Хм, а как ее можно отладить еще?
> Ты ж я вно какой-то запрос должна делать, чтоб использовать
> UDF, а запрос сервер сам себе сгенерировать не может.
я имела ввиду не в приложени, а в утилите(IBExpert) запрос пишу. А отладить как написано в статье нет.
Desdechado (2007-12-14 20:52:00) [67]> UDF я отлаживаю не в клиенте конечно же
Хм, а как ее можно отладить еще?
Ты ж я вно какой-то запрос должна делать, чтоб использовать UDF, а запрос сервер сам себе сгенерировать не может.
trubin (2007-12-14 19:41:00) [68]
> ПРиводи полный текст своей udf dll
+1
irish_34 (2007-12-14 18:47:00) [69]
> Кто выдает ошибку - клиентская программа или сервер?
> Если клиентская программа, то дело не в UDF
UDF я отлаживаю не в клиенте конечно же
Правильный_Вася (2007-12-14 11:40:00) [70]> после отключения от базы выдает ошибку
Кто выдает ошибку - клиентская программа или сервер?
Если клиентская программа, то дело не в UDF.
Сергей М. (2007-12-14 11:16:00) [71]
> irish_34 (13.12.07 18:25) [29]
ПРиводи полный текст своей udf dll
irish_34 (2007-12-13 18:25:00) [72]Вроде работает, но после отключения от базы выдает ошибку "инстукция по адресу 0Х00000000 обратилась к памяти по адресу 0Х00000000
Desdechado (2007-12-12 20:56:00) [73]> trubin © (12.12.07 17:08) [27]
Считай, что спереди стоит
function Malloc( nSize: LongInt ): PChar; cdecl; external 'ib_util.dll' name 'ib_util_malloc';
А вообще для FB1.x фиолетово.
;D
trubin (2007-12-12 17:08:00) [74]
> lpStr := Malloc( nLen - nStart + 1 );
Правильнее использовать ib_util_malloc из ib_util.dll
Сергей М. (2007-12-12 15:51:00) [75]
> irish_34 (10.12.07 21:18) [5]
> про BY DESCRIPTOR как раз в статье прочла
То ли ты ее не дочитала, то ли статья, мягко говоря, неважнецкая, но спецификатор BY DESCRIPTOR, если угодно, есть некое подобие спецификатора, указывающего на вариантный тип данных.
Если тип передаваемых/возвращаемых данных заранее известен, то использование этого спецификатора ничем не оправдано и лишь усложняет как код на стороне сервера, так и на стороне UDF
Desdechado (2007-12-12 15:20:00) [76]Верно, подзабыл уже, давно не писал UDF.
Сергей М. (2007-12-12 13:15:00) [77]
> исходное передаваемое значение
Параметром в UDF в любом случае передается копия неких данных, а не сами данные.
Desdechado (2007-12-12 13:07:00) [78]> А есть ли в этом случае резон для malloc() ?
Зависит от того, хочешь ли ты сохранить у сервера исходное передаваемое значение, м.б. важно в ХП.
Сергей М. (2007-12-12 12:26:00) [79]
> Desdechado © (12.12.07 12:22) [21]
А есть ли в этом случае резон для malloc() ?
Или это ты просто в кач-ве отвлеченного примера, иллюстрирующего использование FREE_IT ?
Desdechado (2007-12-12 12:22:00) [80]А, так это ты сервер "уронила". Проблема с манипуляцией паматью.
Вот пример корректной UDF:
{ DECLARE EXTERNAL FUNCTION SubStr
CSTRING( 32765 ), INTEGER, INTEGER
RETURNS CSTRING( 32765 ) FREE_IT
ENTRY_POINT "fn_SubStr" MODULE_NAME "ib_fv";
}
{----- получение подстроки с символа nFrom, всего nCount штук -----}
function fn_SubStr( lpInp: PChar; var nFrom, nCount: Integer ): PChar; cdecl; export;
var
lpStr: PChar;
nLen, nStart, i: Integer;
begin
{--- выделение памяти под ответ ---}
nLen := StrLen( lpInp );
if( nFrom <= 1 ) then
nStart := 0 {--- nFrom - по основанию 1 ---}
else if( nFrom > nLen ) then
nStart := nLen
else
nStart := nFrom - 1; {--- nStart - по основанию 0 ---}
if( nStart + nCount < nLen ) then
nLen := nStart + nCount;
lpStr := Malloc( nLen - nStart + 1 );
{--- заполнение символами ---}
i := nStart;
while( i < nLen ) do
begin
lpStr[ i - nStart ] := lpInp[ i ];
Inc( i );
end;
lpStr[ i - nStart ] := #0;
result := lpStr;
end;