ООП: доступ к методу класса из-вне

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Ответить
Аватара пользователя
debi12345
долгожитель
Сообщения: 5761
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Сообщение debi12345 »

я так понимаю, что не исходники PostgreSQL, а заголовки для расширений? могу посмотреть, если ссылку дадут!

Исходника Постгреса : https://github.com/postgres/postgres
Исходники расширения (вывод суммы прописью на выбор в рублях, узб.сумах или долларах - с родами, падежами и т.п.) приаттачены.
Как там приткнуть Паскаль - ума не приложу. Только если бы весь Постгрес был был на Паскале написан :)
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Аватара пользователя
Лекс Айрин
долгожитель
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград
Контактная информация:

Сообщение Лекс Айрин »

мда... если честно, то тоже я не понимаю необходимость макросов в паскале. Видимо, это сделано в угоду сишникам.
Аватара пользователя
debi12345
долгожитель
Сообщения: 5761
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Сообщение debi12345 »

то тоже я не понимаю необходимость макросов в паскале.

В том виде, как сделано (нельзя передавать параметры) - тоже не понимаю. Получилась чисто отписка.
SSerge
энтузиаст
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

Сообщение SSerge »

Лекс Айрин писал(а):Видимо, это сделано в угоду сишникам.


А есть ли макросы в дельфях? Если и там - такие же, то уже видимо, в чью это угоду сделано :D
Аватара пользователя
Лекс Айрин
долгожитель
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград
Контактная информация:

Сообщение Лекс Айрин »

debi12345 писал(а):В том виде, как сделано (нельзя передавать параметры) - тоже не понимаю.


А если передавать, тоже особого смысла нет -- это будут те же функции/процедуры.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
Сообщения: 1409
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Сообщение Sergei I. Gorelkin »

Макросы в FPC сделаны для совместимости с диалектом MacPas, насколько я понимаю.
скалогрыз
долгожитель
Сообщения: 1804
Зарегистрирован: 03.09.2008 02:36:48

Сообщение скалогрыз »

debi12345 писал(а):Как там приткнуть Паскаль - ума не приложу. Только если бы весь Постгрес был был на Паскале написан

Очень разумное суждение, если разработчики API не ориентировались на препроцессор, то API был бы намного лучше.

debi12345 писал(а):Исходника Постгреса : https://github.com/postgres/postgres

хорошо. Предлагаю хотя бы одну функцию рассмотреть.

Код: Выделить всё

Datum
numeric_in(PG_FUNCTION_ARGS)
{
   char      *str = PG_GETARG_CSTRING(0);

#ifdef NOT_USED
   Oid         typelem = PG_GETARG_OID(1);
#endif
   int32      typmod = PG_GETARG_INT32(2);
   NumericVar   value;
   Numeric      res;

   /*
    * Check for NaN
    */
   if (pg_strcasecmp(str, "NaN") == 0)
      PG_RETURN_NUMERIC(make_result(&const_nan));

   /*
    * Use set_var_from_str() to parse the input string and return it in the
    * packed DB storage format
    */
   init_var(&value);
   set_var_from_str(str, &value);

   apply_typmod(&value, typmod);

   res = make_result(&value);
   free_var(&value);

   PG_RETURN_NUMERIC(res);
}

Вся свистопляска PG_ макросов начинается с PG_FUNCTION_ARGS.
PG_FUNCTION_ARGS - диктует имя параметра переданного в функцию fcinfo (тип FunctionCallInfo)
Все остальные макросы вроде PG_GETARG_CSTRING или PG_GETARG_INT32, реализованы через PG_GETARG_DATUM, который строго привязан к PG_FUNCTION_ARGS, т.к. зависит от имени параметра функции fcinfo.

Перенести на паскаль один в один не получится, но если добавить в получающиеся PG_хххх функции параметр для fcinfo, то остальное переносится на раз.

хеадер ( ;) ) postgresapi в паскале может выглядеть примерно так:

Код: Выделить всё

unit postgresapi;

interface

const
  FUNC_MAX_ARGS = 100;
type
  Datum = PtrUInt;

  FunctionCallInfoData = record
     // blah
     arg : array [0..FUNC_MAX_ARGS-1] of Datum;
     // blah
  end;
  FunctionCallInfo = ^FunctionCallInfoData;

function PG_GETARG_DATUM(fcinfo: FunctionCallInfo; n: integer): Integer;  inline;
function PG_GETARG_INT32(fcinfo: FunctionCallInfo; n: integer): Integer; inline;
function PG_GETARG_CSTRING(fcinfo: FunctionCallInfo; n: integer): PChar; inline; // DatumGetCString(PG_GETARG_DATUM(n))

function DatumGetInt32(const d: Datum): Integer; inline;
function DatumGetCString(const d: Datum): PChar; inline;
function DatumGetPointer(const d: Datum): Pointer; inline;
function GET_4_BYTES(const d: Datum): LongWord; inline;

implementation

function GET_4_BYTES(const d: Datum): LongWord; inline;
begin
  Result:=d and $FFFFFFFF;
end;

function PG_GETARG_DATUM(fcinfo: FunctionCallInfo; n: integer): Datum;
begin
  Result:=fcinfo^.arg[n];
end;

function PG_GETARG_INT32(fcinfo: FunctionCallInfo; n: integer): Integer;
begin
  Result:=DatumGetInt32(PG_GETARG_DATUM(fcinfo, n)); 
end;

function DatumGetInt32(const d: Datum): Integer; inline;
begin
  Result:=Integer(GET_4_BYTES(d));
end;

function PG_GETARG_CSTRING(fcinfo: FunctionCallInfo; n: integer): PChar; inline;
begin
  Result:=DatumGetCString(PG_GETARG_DATUM(fcinfo, n));
end;

function DatumGetCString(const d: Datum): PChar; inline;
begin
  Result:=PChar(DatumGetPointer(d));
end;

function DatumGetPointer(const d: Datum): Pointer; inline;
begin
  Result:=Pointer(d);
end;

end.


соотстветнно использование этих функций следующее. Основное отличие от С, что fcinfo нужно передавать явно.

Код: Выделить всё

uses 
  postgres;

function  numeric_in(fcinfo: FunctionCallInfo): Datum;
var
  str: PChar;
  typmod: integer;
begin
  str := PG_GETARG_CSTRING(fcinfo, 0);
  ...
  typmod := PG_GETARG_INT32(fcinfo, 2);


Ковырять дальше к PG_RETURN_NUMERIC , или конкретные места интересуют?
Аватара пользователя
debi12345
долгожитель
Сообщения: 5761
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Сообщение debi12345 »

Ковырять дальше к PG_RETURN_NUMERIC , или конкретные места интересуют?

Там часто меняются всякие мелочи - мэйнтэйнить изменения будет геморройно, я именно поэтому не стал упираться. Правда сейчас Постгрес перешел на GitHub и поэтому можно видеть конкретные диффы с комментами - что резко упрощает задачу.
Выгод от FPC в плане работы с ядром, Постгресом и т.п. можно получить немало -в 1-ю очередь легкую, быструю и надежную работу с строками, динамическими массивами, встроенную локализацию и т.п.
Интересно было бы получить 100% рабочее расширение. Этот (из аттача) тип расширений кстати самый сложный по реализации, так как имеет завязки на NUMERIC-тип и локализацию текста - основную массу расширений значительно проще адаптировать. Основный хэдер для адаптации расширений - "fmgr.h" и его субинклуды.
скалогрыз
долгожитель
Сообщения: 1804
Зарегистрирован: 03.09.2008 02:36:48

Сообщение скалогрыз »

debi12345 писал(а):Там часто меняются всякие мелочи - мэйнтэйнить изменения будет геморройно, я именно поэтому не стал упираться.

Геморройно будет только первый раз. После завершения будет в удовольствие.
Наврятли Постргрес будут вносить серьёзные изменения в функции, т.к. бинарная совместимость им может пригодится.

debi12345 писал(а):Интересно было бы получить 100% рабочее расширение.

это предложение мне его сделать? :D

debi12345 писал(а): кстати самый сложный по реализации, так как имеет завязки на NUMERIC-тип и локализацию текста

А вот и начинание numeric-типа:

Код: Выделить всё

unit numeric_int;

interface

uses ctypes;

const
  NUMERIC_POS          = $0000;
  NUMERIC_NEG               = $4000;
  NUMERIC_NAN               = $C000;
  NUMERIC_NULL          = $F000;
  NUMERIC_MAX_PRECISION       = 1000;
  NUMERIC_MAX_DISPLAY_SCALE = NUMERIC_MAX_PRECISION;
  NUMERIC_MIN_DISPLAY_SCALE = 0;
  NUMERIC_MIN_SIG_DIGITS    = 16;

type
  NumericDigit = byte;
  TNumericDigitArray = array [word] of NumericDigit;
  PNumericDigitArray = ^TNumericDigitArray;

  NumericVar = packed record
    ndigits : cint;        {* # of digits in digits[] - can be 0! *}
    weight  : cint;        {* weight of first digit *}
    sign    : cint;        {* NUMERIC_POS, NUMERIC_NEG, or NUMERIC_NAN *}
    dscale  : cint;        {* display scale *}
    buf     : PNumericDigitArray; {* start of palloc'd space for digits[] *}
    digits  : PNumericDigitArray; {* base-NBASE digits *}
  end;

const
  const_nan : NumericVar = (ndigits:0; weight:0; sign:NUMERIC_NAN; dscale:0; buf:nil; digits:nil);

implementation

end.
Аватара пользователя
debi12345
долгожитель
Сообщения: 5761
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Сообщение debi12345 »

Добавлено спустя 4 минуты 17 секунд:
это предложение мне его сделать?

Если сами пользуетесь постгресом и чувствуете в себе силы - то сам доктор прописал :)
Там еще вопрос как сделать make-файл, как заюзать O/A-объектные файлы, созданные С там, где понадобится статическая линковка.

Кстати в аттаче "numeric_*"-файлы - нарезки-солянка из нескольких файлов из PosgreSQL-исходников, без этой солянки у меня почему-то не собиралось.
скалогрыз
долгожитель
Сообщения: 1804
Зарегистрирован: 03.09.2008 02:36:48

Сообщение скалогрыз »

debi12345 писал(а):Если сами пользуетесь постгресом и чувствуете в себе силы - то сам доктор прописал :)

Если бы я пользовался постгресом, то наверное давно бы всё это написал, но не пользуюсь.
Всё это к тому, что Си-шный препроцессор возможно и удобен для Си (за не имением ничего другого). Но со стороны является отличным обфускатором.
И в паскале макросы не нужны, особенно при работе с Си кодом.

debi12345 писал(а):Там еще вопрос как сделать make-файл, как заюзать O/A-объектные файлы, созданные С там, где понадобится статическая линковка.
да, есть свои тонкости, особенно когда надо дружить pascal run-time с Си-шными программами. Но люди и такое делают, и при желании информацию можно найти.

debi12345 писал(а):Кстати в аттаче "numeric_*"-файлы - нарезки-солянка из нескольких файлов из PosgreSQL-исходников, без этой солянки у меня почему-то не собиралось.

Бывает. Многие Си проекты/библиотеки требуют подобной (до)сборки.
zub
долгожитель
Сообщения: 2890
Зарегистрирован: 14.11.2005 22:51:26
Контактная информация:

Сообщение zub »

debi12345
Array of <type> => SetLength(<array>,<elements_of_type>) ? Это идеальный по эффективности способ.

Мне нужны разнотипные элементы
Аватара пользователя
debi12345
долгожитель
Сообщения: 5761
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Сообщение debi12345 »

Хм, старички динамические массивы в 1.5 раза быстрее, чем STL:

Код: Выделить всё

program test_dynarr;
{$mode objfpc}{$h+}

uses
  sysutils,strings;

const
  TEST_CNT = 300000;

type

  chmorec = packed record
    int_val: integer;
    str_val: pchar;
  end;
  pchmorec = ^chmorec;

  ANYTYPE = (INT_T,TEXT_T,REAL_T,CHMO_T);

  anydatarecty = packed record
    case data_type:ANYTYPE of
      INT_T:  (ival: integer);
      TEXT_T: (tval: pchar);
      REAL_T: (rval: double);
      CHMO_T: (chmoval: chmorec);
  end;

var
  arr1: array of anydatarecty;
  chmo1: chmorec;
  i: integer;

begin

  setlength(arr1,TEST_CNT*4);
  for i:= 0 to TEST_CNT-1 do begin
    arr1[i].ival:= i;
   arr1[i + TEST_CNT].rval:= double(i+1);
    arr1[i + TEST_CNT*2].tval:= pchar(inttostr(i) + ' as text');
//    chmo1.int_val:= i;
//    chmo1.str_val:= pchar(inttostr(i) +' as text in CHMOREC');
   arr1[i + TEST_CNT*3].chmoval.int_val:= i;
    arr1[i + TEST_CNT*3].chmoval.str_val:= pchar(inttostr(i) +' as text in CHMOREC');
  end;   
  for i:= 0 to TEST_CNT-1 do begin
    arr1[i].ival:= arr1[i].ival +1;
  end;
//  setlength(arr1,0);

end.

на многих запусках (1-й запуск наоборот в 1.5 раза медленнее).
zub
долгожитель
Сообщения: 2890
Зарегистрирован: 14.11.2005 22:51:26
Контактная информация:

Сообщение zub »

>>Хм, старички динамические массивы в 1.5 раза быстрее, чем STL:
нет. fpc-stl это небольшая надстройка над динмассивами, поэтому скорость у них практически одинаковая.
Ваш тест чуть чуть врёт))

Код: Выделить всё

setlength(arr1,TEST_CNT*4);

т.е. вы выделили сразу TEST_CNT*4 эрементов, потом их заполнили в цикле.
В варианте fpc-stl вы просто инициализзируете массив, не указывая сколько элементов в итоге вы хотите получить. Емнип fpc-stl начинает с длинны массива 1, потом по заполнению увеличивает ее 2 раза.
Такчто либо добавляйте поэлементно в диначический массив, либо выделяйте за раз TEST_CNT*4 элементов в fpc-stl. Иначе это сравнение ужа с ежем
Аватара пользователя
debi12345
долгожитель
Сообщения: 5761
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Сообщение debi12345 »

Так что либо добавляйте поэлементно в диначический массив, либо выделяйте за раз TEST_CNT*4 элементов в fpc-stl. Иначе это сравнение ужа с ежем

В реальных задачах заказывают место не поэлементно, а порциями с запасом - тем более что по потреблению памяти этот вариант экономнее, чем прочие, в 3..5 раз (смотрел https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/time-windows/TimeMem-1.0.exe ) .

Код: Выделить всё

D:fpc_testcasesalgo_test>TimeMem-1.0.exe test-stl.exe
Exit code      : 0
Elapsed time   : 0.27
Kernel time    : 0.02 (5.7%)
User time      : 0.23 (85.7%)
page fault #   : 24239
Working set    : 64724 KB
Paged pool     : 80 KB
Non-paged pool : 5 KB
Page file size : 75900 KB

D:fpc_testcasesalgo_test>TimeMem-1.0.exe test-dynarr.exe
Exit code      : 0
Elapsed time   : 0.19
Kernel time    : 0.02 (8.4%)
User time      : 0.16 (83.9%)
page fault #   : 5606
Working set    : 22332 KB
Paged pool     : 80 KB
Non-paged pool : 4 KB
Page file size : 20256 KB

Кстати я использовал самый неудобный для CPU-кэша способ заполнения и доступа - не последовательные индексы, а с большИми скачками.

Добавлено спустя 3 минуты 32 секунды:
fpc-stl это небольшая надстройка над динмассивами, поэтому скорость у них практически одинаковая.

Не впевен - потому что слишком большая (3 раза) разница в потреблении памяти.
Ответить