Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

UDF [D7, XP]


Страницы:   1 2 3 4 5

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 ?


Страницы:   1 2 3 4 5

Наверх

Титульная страница Поиск, карта сайта Написать письмо