![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Что неверно в UDF?
Андрей Жук © (2005-07-26 16:14:00)
library UnixToWinDate;
uses DateUtils, consts, ibutil,SysUtils;
procedure UnixDateToWinDate(var Ret: TIBTimeStamp;UnixDate: double);cdecl;export;
var
vDate: TDateTime;
YEAR,MONTH,DAY,HOUR,MINUTE,SECOND,MSEC: WORD;
begin
vDate := DateUtils.UnixToDateTime(Round(UnixDate));
DecodeDate(vDate,YEAR,MONTH,DAY);
DecodeTime(vDate,HOUR,MINUTE,SECOND,MSEC);
Ret.Date := IBEncodeDate(YEAR,MONTH,DAY);
Ret.Time := IBEncodeTime(HOUR,MINUTE,SECOND);
end;
exports UnixDateToWinDate;
end.
результат - всегда 01.01.1970
Digitman (2005-07-26 17:40:00) [1]
> Fay © (26.07.05 17:36) [20]
да тот самый)
если ИБ выделил 8 байт , записал туда черт-те что и передал тебе адрес этих 8-ми байт, то ты волен прочитать/записать оттуда/туда все что угодно
Fay (2005-07-26 17:36:00) [2]2 Digitman © (26.07.05 16:56) [18]
А какой вывод из этого нужно сделать головой?
Андрей Жук (2005-07-26 17:03:00) [3]сори, клиент заглючил
Digitman (2005-07-26 16:56:00) [4]
> Андрей Жук
для тех кто на бронепоезде - форматы "дата+время", будь то юниксовые, будь то дельфийские, будь то интербезовы, все они занимают 8 байт, а значит совместимы по размеру с ИБ-типами timestamp, double precision
далее думаем головой ...
Digitman (2005-07-26 16:53:00) [5]
> Johnmen © (26.07.05 16:50) [14]
Беззубый я уже, Жень)
Мне кажется, только БоняПарт ноне не знает, что в IB UDF-параметры передаются по ссылке на копию оригинала
Digitman (2005-07-26 16:51:00) [6]
> Андрей Жук
АБСОЛЮТНО ВСЕ UDF-параметры передаются по ссылке на копию оригинала.
Lexer (2005-07-26 16:51:00) [7]ну и что? (с)
=)
да, к концу дня заметно у всех башка слетает...
Johnmen (2005-07-26 16:50:00) [8]>Digitman © (26.07.05 16:48) [12]
Он заспамить решил, в отместку за то, что ты не разжевал...:)
Digitman (2005-07-26 16:49:00) [9]
> dolmat (26.07.05 16:47) [11]
из другой оперы.
хотя и имеет некоторое отношение к "делу"
Digitman (2005-07-26 16:48:00) [10]
> Андрей Жук © (26.07.05 16:46) [10]
кто-то изрядно туп - то ли прокси твой, то ли ..
еще раз - в своем примере я возвращаю рез-т по ссылке на 1-й параметр
dolmat (2005-07-26 16:47:00) [11]35.2.2. Совместимость типов параметров
При описании параметров в БД (оператор DECLARE EXTERNAL FUNC¬TION) и параметров функций в DLL следует помнить о совместимости типов Object Pascal и InterBase:
Тип InterBase Тип Object Pascal
INTEGER Integer
DOUBLE PRECISION Double
CSTRING PChar
DATE IBDateTime = record
// нужно дополнительное
//преобразование значений
Days : Integer;
Msec: Cardinal; end;
Данное соответствие типов верно для случая, когда результат функции передается в базу данных по значению. Для того чтобы результат передавался по значению, необходимо в операторе DECLARE EXTERNAL FUNCTION после слова RETURNS указать слово BY VALUE. В следующем примере объявляется функция DEN типа DATE, содержащаяся в DLL с именем UDFJDLL:
DECLARE EXTERNAL FUNCTION DEN DATE RETURNS INTEGER BY VALUE ENTRY_POINT "Den" MODULE_NAME "udf^dll";
В том случае, если результат работы UDF передается в БД по ссылке, необходимо использовать указатели на соответствующие типы:
InterBase Object Pascal
INTEGER integer
DOUBLE PRECISION ADouble
DATE AIBDateTime
Тип PChar всегда передается по ссылке.
Будем использовать только параметры, передаваемые по значении: поскольку вызовы UDF предполагается осуществлять в SQL-операторах тип SELECT, INSERT, UPDATE, DELETE, а эти операторы не будут изменят содержимое параметров.
35.2.4. Особенности использования в UDF параметров типа даты и времени
Значения InterBase типа DATE в Object Pascal интерпретируются как запись, j состоящая из двух полей - целочисленного знакового и беззнакового.
IBDateTime = record
Days : Integer;
Msec : Cardinal; end;
Для того чтобы перевести значение из формата IBDateTime в формат даты и времени Delphi TDateTime, необходимо произвести следующее преобразование:
flarmDelphi =flamaInterBase.Days -15018 +flamaInterBase.MSec/(MSecsPerDay*10); где константа MSecsPerDay определена в Delphi как число миллисекунд в сутках.
Андрей Жук (2005-07-26 16:46:00) [12]ну и что?
function UnixDateToWinDate(var Ret: TIBTimeStamp;UnixDate: double):PIBTimeStamp;cdecl;export;
var
vDate: TDateTime;
YEAR,MONTH,DAY,HOUR,MINUTE,SECOND,MSEC: WORD;
begin
vDate := DateUtils.UnixToDateTime(Round(UnixDate));
DecodeDate(vDate,YEAR,MONTH,DAY);
DecodeTime(vDate,HOUR,MINUTE,SECOND,MSEC);
Ret.Date := IBEncodeDate(YEAR,MONTH,DAY);
Ret.Time := IBEncodeTime(HOUR,MINUTE,SECOND);
Result := @Ret;
end;
объявляю как
DECLARE EXTERNAL FUNCTION UNIXDATETOWINDATE
TIMESTAMP,
DOUBLE PRECISION
RETURNS TIMESTAMP
ENTRY_POINT 'UnixDateToWinDate' MODULE_NAME 'unixdate'
результат тот же
Андрей Жук (2005-07-26 16:46:00) [13]ну и что?
function UnixDateToWinDate(var Ret: TIBTimeStamp;UnixDate: double):PIBTimeStamp;cdecl;export;
var
vDate: TDateTime;
YEAR,MONTH,DAY,HOUR,MINUTE,SECOND,MSEC: WORD;
begin
vDate := DateUtils.UnixToDateTime(Round(UnixDate));
DecodeDate(vDate,YEAR,MONTH,DAY);
DecodeTime(vDate,HOUR,MINUTE,SECOND,MSEC);
Ret.Date := IBEncodeDate(YEAR,MONTH,DAY);
Ret.Time := IBEncodeTime(HOUR,MINUTE,SECOND);
Result := @Ret;
end;
объявляю как
DECLARE EXTERNAL FUNCTION UNIXDATETOWINDATE
TIMESTAMP,
DOUBLE PRECISION
RETURNS TIMESTAMP
ENTRY_POINT 'UnixDateToWinDate' MODULE_NAME 'unixdate'
результат тот же
Андрей Жук (2005-07-26 16:46:00) [14]ну и что?
function UnixDateToWinDate(var Ret: TIBTimeStamp;UnixDate: double):PIBTimeStamp;cdecl;export;
var
vDate: TDateTime;
YEAR,MONTH,DAY,HOUR,MINUTE,SECOND,MSEC: WORD;
begin
vDate := DateUtils.UnixToDateTime(Round(UnixDate));
DecodeDate(vDate,YEAR,MONTH,DAY);
DecodeTime(vDate,HOUR,MINUTE,SECOND,MSEC);
Ret.Date := IBEncodeDate(YEAR,MONTH,DAY);
Ret.Time := IBEncodeTime(HOUR,MINUTE,SECOND);
Result := @Ret;
end;
объявляю как
DECLARE EXTERNAL FUNCTION UNIXDATETOWINDATE
TIMESTAMP,
DOUBLE PRECISION
RETURNS TIMESTAMP
ENTRY_POINT 'UnixDateToWinDate' MODULE_NAME 'unixdate'
результат тот же
Digitman (2005-07-26 16:44:00) [15]
> ну и что?
нуичтокай побольше - думать меньше придется
> RETURNS TIMESTAMP
это - возврат по значению.
в моем же примере - возврат по ссылке на 1-й параметр.
Андрей Жук (2005-07-26 16:41:00) [16]ну и что?
function UnixDateToWinDate(var Ret: TIBTimeStamp;UnixDate: double):PIBTimeStamp;cdecl;export;
var
vDate: TDateTime;
YEAR,MONTH,DAY,HOUR,MINUTE,SECOND,MSEC: WORD;
begin
vDate := DateUtils.UnixToDateTime(Round(UnixDate));
DecodeDate(vDate,YEAR,MONTH,DAY);
DecodeTime(vDate,HOUR,MINUTE,SECOND,MSEC);
Ret.Date := IBEncodeDate(YEAR,MONTH,DAY);
Ret.Time := IBEncodeTime(HOUR,MINUTE,SECOND);
Result := @Ret;
end;
объявляю как
DECLARE EXTERNAL FUNCTION UNIXDATETOWINDATE
TIMESTAMP,
DOUBLE PRECISION
RETURNS TIMESTAMP
ENTRY_POINT 'UnixDateToWinDate' MODULE_NAME 'unixdate'
результат тот же
Андрей Жук (2005-07-26 16:40:00) [17]ну и что?
function UnixDateToWinDate(var Ret: TIBTimeStamp;UnixDate: double):PIBTimeStamp;cdecl;export;
var
vDate: TDateTime;
YEAR,MONTH,DAY,HOUR,MINUTE,SECOND,MSEC: WORD;
begin
vDate := DateUtils.UnixToDateTime(Round(UnixDate));
DecodeDate(vDate,YEAR,MONTH,DAY);
DecodeTime(vDate,HOUR,MINUTE,SECOND,MSEC);
Ret.Date := IBEncodeDate(YEAR,MONTH,DAY);
Ret.Time := IBEncodeTime(HOUR,MINUTE,SECOND);
Result := @Ret;
end;
объявляю как
DECLARE EXTERNAL FUNCTION UNIXDATETOWINDATE
TIMESTAMP,
DOUBLE PRECISION
RETURNS TIMESTAMP
ENTRY_POINT 'UnixDateToWinDate' MODULE_NAME 'unixdate'
результат тот же
Андрей Жук (2005-07-26 16:40:00) [18]ну и что?
function UnixDateToWinDate(var Ret: TIBTimeStamp;UnixDate: double):PIBTimeStamp;cdecl;export;
var
vDate: TDateTime;
YEAR,MONTH,DAY,HOUR,MINUTE,SECOND,MSEC: WORD;
begin
vDate := DateUtils.UnixToDateTime(Round(UnixDate));
DecodeDate(vDate,YEAR,MONTH,DAY);
DecodeTime(vDate,HOUR,MINUTE,SECOND,MSEC);
Ret.Date := IBEncodeDate(YEAR,MONTH,DAY);
Ret.Time := IBEncodeTime(HOUR,MINUTE,SECOND);
Result := @Ret;
end;
объявляю как
DECLARE EXTERNAL FUNCTION UNIXDATETOWINDATE
TIMESTAMP,
DOUBLE PRECISION
RETURNS TIMESTAMP
ENTRY_POINT 'UnixDateToWinDate' MODULE_NAME 'unixdate'
Digitman (2005-07-26 16:36:00) [19]function UnixDateToWinDate(var UnixDate: double): PIBTimeStamp; cdecl;
var
vDate: TDateTime;
YEAR,MONTH,DAY,HOUR,MINUTE,SECOND,MSEC: WORD;
begin
vDate := DateUtils.UnixToDateTime(Round(UnixDate));
DecodeDate(vDate,YEAR,MONTH,DAY);
DecodeTime(vDate,HOUR,MINUTE,SECOND,MSEC);
Result := @Unixdate;
Result.Date := IBEncodeDate(YEAR,MONTH,DAY);
Result.Time := IBEncodeTime(HOUR,MINUTE,SECOND);
end;
Digitman (2005-07-26 16:31:00) [20]
> здесь нужна фунция
так точно, сэр !
> Андрей Жук © (26.07.05 16:14)
думай ... над сказанным ...