Форум: "Начинающим";
Текущий архив: 2008.01.27;
Скачать: [xml.tar.bz2];
ВнизUDF Найти похожие ветки
← →
Irish_34 (2007-12-10 20:02) [0]Привет ВСЕМ, помогите пожалусто 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;
← →
Johnmen © (2007-12-10 20:11) [1]http://www.ibase.ru/devinfo/udf_ok.htm
← →
irish_34 (2007-12-10 20:17) [2]Перечитала....
← →
trubin © (2007-12-10 20:56) [3]1)
> RETURNS VARCHAR(50) BY DESCRIPTOR
зачем "by descriptor", надо "FREE_IT"
2)
Память под Result не выделяется
3)
> s1:=PChar(s)^;
s1:= string(s);
← →
irish_34 (2007-12-10 21:17) [4]Спасибо большое :*
а без "FREE_IT" разве ни как нельзя....
← →
irish_34 (2007-12-10 21:18) [5]а про BY DESCRIPTOR как раз в статье прочла
← →
Desdechado © (2007-12-10 22:14) [6]Нужно не лепить их бездумно, а понимать, для чего они. FREE_IT, наприер, нужно для того, чтобы сервер освободил выделенную в UDF (и вовзернутую ему) память после того, как она стала не нужна.
← →
irish_34 (2007-12-10 22:26) [7]ну значит и не надо вовлекать сюда FREE_IT, BY DESCRIPTOR по написанному (в тоё же статье) с null позволяет работать, хотя в этой суюд и без него нормально всё работало
← →
irish_34 (2007-12-10 22:34) [8]но судя по попытке запроса выполниться ошибка не в регистрации UDF
← →
Desdechado © (2007-12-10 22:49) [9]> но судя по попытке запроса выполниться ошибка не в регистрации UDF
Увы, я, не видя ошибки, ничего посоветовать не могу.
← →
Desdechado © (2007-12-10 22:50) [10]Кроме того, не все модификаторы доступны в разных версиях IB|FB. А ты даже сам сервер не указало, так что о чем речь?
← →
irish_34 (2007-12-10 22:54) [11]FB1
← →
trubin © (2007-12-10 22:59) [12]Пишешь "by descriptor", только не видно, где ты у себя в функции используешь структуру дескриптора параметра. А на null можно и проверку в ХП делать.
← →
Desdechado © (2007-12-10 23:00) [13]1.что_дальше?
Текст ошибки где?
Терпение не резиновое...
← →
Desdechado © (2007-12-10 23:03) [14]> (var s:PChar)
Зачем это?
← →
irish_34 (2007-12-10 23:10) [15]системная ошибка из-за выражения которое не может успешно выполниться
написано что так следует передавать параметр в UDF
← →
Сергей М. © (2007-12-11 08:11) [16]
> Irish_34
Что должна делать эта функция ?
← →
irish_34 (2007-12-11 18:31) [17]
> Сергей М.
выделить часть строки после "6" без разделителей
← →
Сергей М. © (2007-12-12 08:40) [18]Т.е. результирующая строка не может быть длиннее исходной ?
Тогда можно поступить проще:DECLARE EXTERNAL FUNCTION CEX6
VARCHAR(50)
RETURNS PARAMETER 1
ENTRY_POINT "psc6" MODULE_NAME "PDL6.dll"
function psc6(AString:PChar):PChar; cdecl;
var
tmpstr: String;
..
begin
tmpstr := AString;
... работа с локальной копией (tmpstr) исходной строки в соответствии с [17]
.. результат обработки подразумевается находящимся там же, т.е. в tmpstr
Result := lstrcpy(AString, PChar(tmpstr)); //возврат результата
end;
← →
Desdechado © (2007-12-12 08:47) [19]> системная ошибка из-за выражения которое не может успешно
> выполниться
Да ну? А я думал, FB по-русски не ругается.
← →
irish_34 (2007-12-12 12:10) [20]
> Desdechado ©
Unsuccessful execution caused by a system error that precludes
Successful execution of subsequent statements.
Unable to complete network request to host “”.
Error reading data from the connection.
← →
Desdechado © (2007-12-12 12:22) [21]А, так это ты сервер "уронила". Проблема с манипуляцией паматью.
Вот пример корректной 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;
← →
Сергей М. © (2007-12-12 12:26) [22]
> Desdechado © (12.12.07 12:22) [21]
А есть ли в этом случае резон для malloc() ?
Или это ты просто в кач-ве отвлеченного примера, иллюстрирующего использование FREE_IT ?
← →
Desdechado © (2007-12-12 13:07) [23]> А есть ли в этом случае резон для malloc() ?
Зависит от того, хочешь ли ты сохранить у сервера исходное передаваемое значение, м.б. важно в ХП.
← →
Сергей М. © (2007-12-12 13:15) [24]
> исходное передаваемое значение
Параметром в UDF в любом случае передается копия неких данных, а не сами данные.
← →
Desdechado © (2007-12-12 15:20) [25]Верно, подзабыл уже, давно не писал UDF.
← →
Сергей М. © (2007-12-12 15:51) [26]
> irish_34 (10.12.07 21:18) [5]
> про BY DESCRIPTOR как раз в статье прочла
То ли ты ее не дочитала, то ли статья, мягко говоря, неважнецкая, но спецификатор BY DESCRIPTOR, если угодно, есть некое подобие спецификатора, указывающего на вариантный тип данных.
Если тип передаваемых/возвращаемых данных заранее известен, то использование этого спецификатора ничем не оправдано и лишь усложняет как код на стороне сервера, так и на стороне UDF
← →
trubin © (2007-12-12 17:08) [27]
> lpStr := Malloc( nLen - nStart + 1 );
Правильнее использовать ib_util_malloc из ib_util.dll
← →
Desdechado © (2007-12-12 20:56) [28]> trubin © (12.12.07 17:08) [27]
Считай, что спереди стоитfunction Malloc( nSize: LongInt ): PChar; cdecl; external "ib_util.dll" name "ib_util_malloc";
А вообще для FB1.x фиолетово.
;D
← →
irish_34 (2007-12-13 18:25) [29]Вроде работает, но после отключения от базы выдает ошибку "инстукция по адресу 0Х00000000 обратилась к памяти по адресу 0Х00000000
← →
Сергей М. © (2007-12-14 11:16) [30]
> irish_34 (13.12.07 18:25) [29]
ПРиводи полный текст своей udf dll
← →
Правильный_Вася (2007-12-14 11:40) [31]> после отключения от базы выдает ошибку
Кто выдает ошибку - клиентская программа или сервер?
Если клиентская программа, то дело не в UDF.
← →
irish_34 (2007-12-14 18:47) [32]
> Кто выдает ошибку - клиентская программа или сервер?
> Если клиентская программа, то дело не в UDF
UDF я отлаживаю не в клиенте конечно же
← →
trubin © (2007-12-14 19:41) [33]
> ПРиводи полный текст своей udf dll
+1
← →
Desdechado © (2007-12-14 20:52) [34]> UDF я отлаживаю не в клиенте конечно же
Хм, а как ее можно отладить еще?
Ты ж я вно какой-то запрос должна делать, чтоб использовать UDF, а запрос сервер сам себе сгенерировать не может.
← →
irish_34 (2007-12-15 11:16) [35]
> Хм, а как ее можно отладить еще?
> Ты ж я вно какой-то запрос должна делать, чтоб использовать
> UDF, а запрос сервер сам себе сгенерировать не может.
я имела ввиду не в приложени, а в утилите(IBExpert) запрос пишу. А отладить как написано в статье нет.
← →
irish_34 (2007-12-15 11:16) [36]
> ПРиводи полный текст своей 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:18) [37]кстати заработала она не от "result:=malloc(6); result[6]:=#0;", а от того что я удалила цикл и удалила перебор символов строки (s[i])
← →
Сергей М. © (2007-12-15 12:45) [38]
> uses ShareMem
Это еще зачем ?
← →
irish_34 (2007-12-15 13:22) [39]
> Это еще зачем ?
для работы со строками, но на работу никак не влияет
← →
Сергей М. © (2007-12-15 13:32) [40]
> для работы со строками
Это из другой оперы.
Убирай.
> на работу никак не влияет
>
Влияет. Не лучшим образом. Просто ты этого не ощущаешь.
Страницы: 1 2 3 вся ветка
Форум: "Начинающим";
Текущий архив: 2008.01.27;
Скачать: [xml.tar.bz2];
Память: 0.54 MB
Время: 0.008 c