![]() |
| ||
|
|
Новости |
Поиск |
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-17 08:43:00) [41]
> irish_34 (16.12.07 13:14) [51]
> если с ней предполагается работа только одной нити?
Кем предполагается, тобой ?
Ты можешь предполагать что угодно, но сервер волен вызывать твою ф-цию в любой нити, в какой он сочтет необходимым.
palva (2007-12-16 17:08:00) [42]Ну значит ошибки нужно искать, доводить до ума.
Вот я написал пример. Только надо вставить проверки случаев, когда не найдено, здесь я вашу логику все равно в упор не понимаю.
{$APPTYPE CONSOLE}
uses SysUtils;
function strpbrk(str, strCharSet: PChar): PChar; cdecl; external 'msvcrt.dll';
function psc6(s: PChar): PChar; cdecl
const
set1: array [0..4] of char = ',.; '#0;
set2: array [0..5] of char = ',.; )'#0;
var
p: PChar;
begin
p := strpos(s, '6');
p := strpbrk(p, set1) + 1;
Result := p;
p := strpbrk(p, set2);
if p <> Nil then p^ := char(0);
end;
/////////// Testing /////////
var
s: String;
begin
s := '6___,rtytwey rzxt';
WriteLn(psc6(PChar(s))); // rtytwey
s := '6sdf,rty';
WriteLn(psc6(PChar(s))); // rty
end.
irish_34 (2007-12-16 16:52:00) [43]
> Автор, наверно вмешаюсь не в свое дело, но посоветую следующее.
>
> 1) не нужно выделять память в функции. Вы можете возвращать
> указатель на часть входного параметра, обрезав его если
> надо нулем. Это гораздо проще.
почему не в свое, это же форум. я первый пунк я пробовала, вообще отключает сервер
palva (2007-12-16 16:36:00) [44]Автор, наверно вмешаюсь не в свое дело, но посоветую следующее.
1) не нужно выделять память в функции. Вы можете возвращать указатель на часть входного параметра, обрезав его если надо нулем. Это гораздо проще.
2) если уж вам пришлось работать с си-строками, то не преобразуйте их в паскалевские строки. В Delphi вполне достаточно функций для работы с си-строками. Постарайтесь вообще обойтись без строк и строковых функций делфи.
3) Для данной функции советую использовать сишную функцию strpbrk, которая экспортируется библиотекой msvcrt.dll Она ищет в строке (заданной первым параметром) один из символов, содержащийся в другой строке (второй параметр), и возвращает указатель на найденный символ либо NULL. Эта функция как будто специально написана для вас.
palva (2007-12-16 16:18:00) [45]> Это допустимый максимум, а не длина фактического значения.
Ну то есть вы даете гарантию, что сервер не полезет читать возвращенный буфер дальше нулевого байта. Я, например, этого не знаю. Лезть в документацию и исходники мне влом. Соответственно, я задаю вопрос автору зачем он так сделал. Зачем автор сделал выравнивание текста не соответствующее логике программы? Неужели он думает, что отвечающий скопирует текст себе в редактор и будет его выравнивать? На самом деле большинство потенциальных отвечающих споткнулись об это выравнивание в первых постах и дальше читать не стали. Зачем автор демонстративно нарушает заповеди: если выделил 6 байтов, то седьмой даже читать нельзя.
> Действительно. Это и ставит сервер на колени.
Ну это вряд ли. Обычно память выделяется кусками, кратными восьми. А вот если обращение к UDF произойдет с подходящей длинной строкой, то тогда запросто.
irish_34 (2007-12-16 16:17:00) [46]
> И что за x?
)))))))) эт не хэ это икс
фига се случайность, а чё тада на ошибку памяти 0*00000000 повлияло, завтра конечно посмотрю ещё свою "карявку", ну ни наю даже.......
Desdechado (2007-12-16 16:07:00) [47]> не повлияло на работу
Случайность. Стрка в Pchar обязаназаканчиваться нулем.
И что за x?
irish_34 (2007-12-16 15:55:00) [48]
> Действительно. Это и ставит сервер на колени.
ды его можно вообще не писать, по эксприменту, result[х]:=#0;
не повлияло на работу
Desdechado (2007-12-16 15:41:00) [49]> А почему при описании UDF она такая большая:CSTRING( 32765 ) ?
Это допустимый максимум, а не длина фактического значения.
> Кроме того, почему памяти выделяется 6 байтов, а нулевой
> бит записывается в 7-й:result[6]:=#0;
Действительно. Это и ставит сервер на колени.
irish_34 (2007-12-16 13:14:00) [50]
> Ё-моё, сколько нафлудили!
> А автору всего-то и надо, что внимательно прочитать статью.
> ..
Вы имеете ввиду использование уникальной для каждой нити глобальной переменной при возврате результата по ссылке и фразу IsMultiThread:=true;?
а если с ней предполагается работа только одной нити?
Johnmen (2007-12-16 00:35:00) [51]Ё-моё, сколько нафлудили!
А автору всего-то и надо, что внимательнопрочитать статью...
palva (2007-12-15 18:40:00) [52]>> Это по условию задачи выходная строка не может быть больше 5-ти символов?
> да
А почему при описании UDF она такая большая:
CSTRING( 32765 ) ?
Вы не боитесь, что FireBird будет как либо использовать эту память перед тем как ее освободит? Например скопирует выходное значение в свою внутреннюю область памяти?
Кроме того, почему памяти выделяется 6 байтов, а нулевой бит записывается в 7-й:
result[6]:=#0;
Что произойдет, если входная строка окажется такой, что выходная строка переполнит выделенный буфер? Контроля ведь никакого не предусмотрено. Или входная строка окажется такой, что переполнятся байтовые переменные i1,j,j1
trubin (2007-12-15 18:28:00) [53]Я так думаю тебе надо быстренько сварганить тестовый проектик, загрузить в нем свою dll-ку, и погонять свою функцию
irish_34 (2007-12-15 16:10:00) [54]
> Это по условию задачи выходная строка не может быть больше
> 5-ти символов?
да
trubin (2007-12-15 16:06:00) [55]
> result:=malloc(6);
Это по условию задачи выходная строка не может быть больше 5-ти символов?
irish_34 (2007-12-15 15:45:00) [56]
> П-п-переведи) ...
))))) ой....
ошибка "инстукция по адресу 0Х00000000 обратилась к памяти по адресу 0Х00000000" нет от подключения этого модуля
Сергей М. (2007-12-15 14:49:00) [57]
> проблему о пяти с инструкцией
П-п-переведи) ...
irish_34 (2007-12-15 14:01:00) [58]
> Влияет. Не лучшим образом. Просто ты этого не ощущаешь.
но проблему о пяти с инструкцией это не решит
irish_34 (2007-12-15 14:00:00) [59]
> Я все-таки не понял. Вы пишете модуль, а потом каким-то
> образом используете его в качестве dll
library PDL6;
uses
UDFL6 in 'UDFL6.pas';
end.
palva (2007-12-15 13:49:00) [60]irish_34 (15.12.07 11:16) [36]
Я все-таки не понял. Вы пишете модуль, а потом каким-то образом используете его в качестве dll ?