Re[6]: Перевести код библиотеки xdr с C++ на Delphi
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 19.09.23 20:32
Оценка:
Здравствуйте, reversecode, Вы писали:

R>ннда

R>если бы я в юности не программил на делфи
R>а в старости не ревесил программы на делфи
R>то наверное я бы и поддался вашим тезисам
Khimik не программист, а реальны химик. Ему чтобы нормально в программирование окунуться нужно года 2-3 учится.
Sic luceat lux!
Re[7]: Перевести код библиотеки xdr с C++ на Delphi
От: reversecode google
Дата: 19.09.23 20:42
Оценка:
он 15 лет на форуме окунается
пора бы уже
Re[8]: Перевести код библиотеки xdr с C++ на Delphi
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 19.09.23 22:12
Оценка: 1 (1)
Здравствуйте, reversecode, Вы писали:

R>он 15 лет на форуме окунается

R>пора бы уже
Человек правильно расставил приоритеты, лутает деньги с дельфии-симулятора и инвестирует в личную жизнь, а не учит это ваше программирование на С++ по 15 чтобы стать сениёром.
Sic luceat lux!
Re[3]: Перевести код библиотеки xdr с C++ на Delphi
От: kov_serg Россия  
Дата: 19.09.23 23:45
Оценка: 1 (1)
Здравствуйте, Khimik, Вы писали:

K>Вы посмотрели функции receivebits и receiveints? Мне ещё не совсем понятно, если в молекуле 100 атомов, xyz координаты каждого упаковываются в одно число и эти числа идут друг за другом, или упаковка идёт ещё дальше и например координаты двух атомов это x1, x2, x3, x4, x5, x6 в вашем примере, которые упаковываются в единое многозначное число.

Смотрите исходник все просто кодируется. Даже описание в шапке есть:
/*____________________________________________________________________________
 |
 | xdr3dfcoord - read or write compressed 3d coordinates to xdr file.
 |
 | this routine reads or writes (depending on how you opened the file with
 | xdropen() ) a large number of 3d coordinates (stored in *fp).
 | The number of coordinates triplets to write is given by *size. On
 | read this number may be zero, in which case it reads as many as were written
 | or it may specify the number if triplets to read (which should match the
 | number written).
 | Compression is achieved by first converting all floating numbers to integer
 | using multiplication by *precision and rounding to the nearest integer.
 | Then the minimum and maximum value are calculated to determine the range.
 | The limited range of integers so found, is used to compress the coordinates.
 | In addition the differences between succesive coordinates is calculated.
 | If the difference happens to be 'small' then only the difference is saved,
 | compressing the data even more. The notion of 'small' is changed dynamically
 | and is enlarged or reduced whenever needed or possible.
 | Extra compression is achieved in the case of GROMOS and coordinates of
 | water molecules. GROMOS first writes out the Oxygen position, followed by
 | the two hydrogens. In order to make the differences smaller (and thereby
 | compression the data better) the order is changed into first one hydrogen
 | then the oxygen, followed by the other hydrogen. This is rather special, but
 | it shouldn't harm in the general case.
 |
 */

google translate:

эта процедура читает или записывает (в зависимости от того, как вы открыли файл с помощью xdropen())
большое количество трехмерных координат (хранящихся в *fp).
Количество записываемых троек координат определяется параметром *size.
При чтении это число может быть нулевым, и в этом случае он считывает столько же, сколько было записано,
или может указывать количество считываемых триплетов (которое должно совпадать с записанным числом).
Сжатие достигается путем предварительного преобразования всех плавающих чисел в целые числа с
использованием умножения на *точность и округления до ближайшего целого числа. Затем вычисляются
минимальное и максимальное значения для определения диапазона. Найденный таким образом ограниченный
диапазон целых чисел используется для сжатия координат. Кроме того, рассчитывается разница между
последовательными координатами. Если разница оказывается «небольшой», сохраняется только разница,
что еще больше сжимает данные. Понятие «маленького» динамически меняется и увеличивается или
уменьшается всякий раз, когда это необходимо или возможно. Дополнительное сжатие достигается в случае
GROMOS и координат молекул воды. GROMOS сначала записывает положение кислорода, а затем двух атомов
водорода. Чтобы сделать различия меньшими (и тем самым лучше сжать данные),
порядок изменяется: сначала один водород, затем кислород, а затем другой водород.
Это довольно специфическая ситуация, но в общем случае она не должна навредить.


K>Я в прошлом правил один код старой научной программы на фортране, и можно сказать был в шоке, насколько фортран неудобный язык или насколько этот код неправильно написан.

Зря вы гоните на фортран. Современный фортран позволяет писать достаточно выразительно.
Re[9]: Перевести код библиотеки xdr с C++ на Delphi
От: reversecode google
Дата: 20.09.23 00:11
Оценка:
синьер нафиг не нужен
на том уровне что ему надо
я начал программить на с/c++ через месяц как увидел и научился включать комп
и мне показали на какие клавиши нажимать что бы запустить компиляцию
Re[7]: Перевести код библиотеки xdr с C++ на Delphi
От: Khimik  
Дата: 20.09.23 09:49
Оценка: :))) :))
Здравствуйте, Kernan, Вы писали:

R>>ннда

R>>если бы я в юности не программил на делфи
R>>а в старости не ревесил программы на делфи
R>>то наверное я бы и поддался вашим тезисам
K>Khimik не программист, а реальны химик. Ему чтобы нормально в программирование окунуться нужно года 2-3 учится.

Мне обидно слышать такие выпады, отвечу что я зарабатываю на шароваре, возможно, больше любого из вас, притом что у меня огромное количество времени уходит на науку, философию, политику и т.п. — кто читает мои посты на форуме, поймёт о чём я. Обычно все специалисты, один я могу на любую тему поговорить.
"Ты должен сделать добро из зла, потому что его больше не из чего сделать". АБ Стругацкие.
Re[8]: Перевести код библиотеки xdr с C++ на Delphi
От: SergeyIT Россия  
Дата: 20.09.23 10:06
Оценка:
Здравствуйте, Khimik, Вы писали:

K>Обычно все специалисты, один я могу на любую тему поговорить.


Оно и видно, что поговорить
Извините, я все еще учусь
Re: Перевести код библиотеки xdr с C++ на Delphi
От: Khimik  
Дата: 20.09.23 15:24
Оценка:
Очень грустно, что никто из обладателей GPT4 на этом форуме не откликнулся на мою просьбу. Казалось бы делов то — скопипастить ему четыре фрагмента кода, или только два первых, из третьего сообщения, плюс добавить "translate this code from C to Delphi programming language". Shmj, vsb, MaximVK, вы могли бы блеснуть суперспособностью...
"Ты должен сделать добро из зла, потому что его больше не из чего сделать". АБ Стругацкие.
Re: Перевести код библиотеки xdr с C++ на Delphi
От: AleksandrN Россия  
Дата: 20.09.23 15:41
Оценка: +3
Здравствуйте, Khimik, Вы писали:

K>Мне надо перевести с C++ на Delphi фрагмент кода программы Gromacs, который читает файл с траекторией движения молекул.


А не лучше этот код на C++ в DLL засунуть и вызывать из Delphi?
Re[2]: Перевести код библиотеки xdr с C++ на Delphi
От: SergeyIT Россия  
Дата: 20.09.23 15:42
Оценка:
Здравствуйте, Khimik, Вы писали:

K> Казалось бы делов то —


взять и переписать, но не тянешь
Извините, я все еще учусь
Re[2]: Перевести код библиотеки xdr с C++ на Delphi
От: pagid_ Россия  
Дата: 20.09.23 16:38
Оценка:
Здравствуйте, AleksandrN, Вы писали:

AN>А не лучше этот код на C++ в DLL засунуть и вызывать из Delphi?

А не дольше в DLL засовывать, чем переписать, руками? Особенно если у ТС нет опыта создания Сшных DLL и вызова их функций из Дельфи. Заодно и понять что код делает. Хотя похоже ТС хотелось использовать код не понимая этого.
Re[3]: Перевести код библиотеки xdr с C++ на Delphi
От: alsemm Россия  
Дата: 20.09.23 18:42
Оценка: +2
Здравствуйте, pagid_, Вы писали:

_>Заодно и понять что код делает.

Зачем? Ему же не ошибки в нем исправлять. Проще потратить время и разобраться как эту либу подружить с дельфи как есть, чем перепиливать ее на паскале. Наделает же ошибок в процессе. Это в довесок к тому, что потратит кучу времени на переписывание.
Re[2]: Перевести код библиотеки xdr с C++ на Delphi
От: Quebecois Канада https://www.canada.ca/
Дата: 20.09.23 20:31
Оценка: +2
Здравствуйте, Khimik, Вы писали:

K>Очень грустно, что никто из обладателей GPT4 на этом форуме не откликнулся на мою просьбу. Казалось бы делов то — скопипастить ему четыре фрагмента кода, или только два первых, из третьего сообщения, плюс добавить "translate this code from C to Delphi programming language". Shmj, vsb, MaximVK, вы могли бы блеснуть суперспособностью...

У меня нет GPT-4, но рискну предположить, что с первого раза он выдаст правдоподобную фигню, и начнется бесконечный цикл уточнений и правок, на который ни у кого нет времени.
Плюс, я не знаю, как низко надо ценить собственное время, чтобы было жалко потратить двадцатку на подписку самому, если это реально надо для бизнеса.
Re: Перевести код библиотеки xdr с C++ на Delphi
От: Артём Австралия жж
Дата: 20.09.23 23:39
Оценка: +2
Здравствуйте, Khimik, Вы писали:

Собери эту xdr как static lib и залинкуй в дельфу. Не страдай *ёй.
Re: Перевести код библиотеки xdr с C++ на Delphi
От: Khimik  
Дата: 24.10.23 12:43
Оценка:
https://rsdn.org/forum/job.offers/8624193.all
Автор: Khimik
Дата: 24.10.23
"Ты должен сделать добро из зла, потому что его больше не из чего сделать". АБ Стругацкие.
Re[2]: Перевести код библиотеки xdr с C++ на Delphi
От: Dimonka Верблюд  
Дата: 24.10.23 14:38
Оценка: 1 (1)
Здравствуйте, Khimik, Вы писали:

Да справляется GPT. Не греши за зря

K>Первая половина:


  GPT4

Here's a translation of the given C code to Delphi:

delphi


function xdr3dfcoord(xdrs: PXDR; fp: PSingle; var size: Integer; precision: PSingle): Integer;
const
  MAXID = ...;  // You should define this value, it was not in the original code.
  FIRSTIDX = ...;  // Similarly, define this value.
  LASTIDX = ...;  // And this value.
var
  ip, buf: PInteger;
  oldsize: Integer;
  minint, maxint, prevcoord: array[0..2] of Integer;
  mindiff, diff, lint1, lint2, lint3, oldlint1, oldlint2, oldlint3, smallidx: Integer;
  minidx, maxidx, flag, k, smallnum, smaller, larger, i, is_small, is_smaller: Integer;
  run, prevrun, tmp, bufsize, xdrid, lsize: Integer;
  bitsize: Cardinal;
  size3: Cardinal;
  sizeint, sizesmall, bitsizeint: array[0..2] of Cardinal;
  luip: PCardinal;
  lfp: PSingle;
  lf: Single;
  thiscoord: PInteger;
  tmpcoord: array[0..29] of Cardinal;
  inv_precision: Single;
  errval: Integer = 1;
begin
  bitsizeint[0] := 0;
  bitsizeint[1] := 0;
  bitsizeint[2] := 0;
  prevcoord[0]  := 0;
  prevcoord[1]  := 0;
  prevcoord[2]  := 0;

  // Assuming xdridptr and xdrmodes are external/global arrays. Their types and sizes are not defined in the provided code.
  xdrid := 0;
  while (xdridptr[xdrid] <> xdrs) do
  begin
    Inc(xdrid);
    if (xdrid >= MAXID) then
    begin
      WriteLn('xdr error. no open xdr stream');
      Halt(1);
    end;
  end;

  if (xdrmodes[xdrid] = 'w') or (xdrmodes[xdrid] = 'a') then
  begin
    // Code for writing mode is skipped as per the original.
  end
  else
  begin
    // Reading mode
    if (xdr_int(xdrs, lsize) = 0) then
      Exit(0);
      
    if (size <> 0) and (lsize <> size) then
      WriteLn(Format('wrong number of coordinates in xdr3dfcoord; %d arg vs %d in file', [size, lsize]));

    size := lsize;
    size3 := Cardinal(size) * 3;

    if size <= 9 then
    begin
      precision^ := -1;
      Exit(xdr_vector(xdrs, PChar(fp), size3, SizeOf(Single), @xdr_float));
    end;

    xdr_float(xdrs, precision^);

    if ip = nil then
    begin
      GetMem(ip, size3 * SizeOf(Integer));
      if ip = nil then
      begin
        WriteLn('malloc failed');
        Halt(1);
      end;

      bufsize := Trunc(size3 * 1.2);
      GetMem(buf, bufsize * SizeOf(Integer));
      if buf = nil then
      begin
        WriteLn('malloc failed');
        Halt(1);
      end;

      oldsize := size;
    end
    else if size > oldsize then
    begin
      ReallocMem(ip, size3 * SizeOf(Integer));
      if ip = nil then
      begin
        WriteLn('malloc failed');
        Halt(1);
      end;

      bufsize := Trunc(size3 * 1.2);
      ReallocMem(buf, bufsize * SizeOf(Integer));
      if buf = nil then
      begin
        WriteLn('malloc failed');
        Halt(1);
      end;

      oldsize := size;
    end;

    buf[0] := 0;
    buf[1] := 0;
    buf[2] := 0;

    xdr_int(xdrs, minint[0]);
    xdr_int(xdrs, minint[1]);
    xdr_int(xdrs, minint[2]);
    xdr_int(xdrs, maxint[0]);
    xdr_int(xdrs, maxint[1]);
    xdr_int(xdrs, maxint[2]);

    sizeint[0] := Cardinal(maxint[0] - minint[0] + 1);
    sizeint[1] := Cardinal(maxint[1] - minint[1] + 1);
    sizeint[2] := Cardinal(maxint[2] - minint[2] + 1);

    // Assuming sizeofint and sizeofints are functions you have elsewhere
    if (sizeint[0] or sizeint[1] or sizeint[2]) > $ffffff then
    begin
      bitsizeint[0] := sizeofint(sizeint[0]);
      bitsizeint[1] := sizeofint(sizeint[1]);
      bitsizeint[2] := sizeofint(sizeint[2]);
      bitsize := 0; // Flag the use of large sizes
    end
    else
      bitsize := sizeofints(3, @sizeint);

    if xdr_int(xdrs, smallidx) = 0 then
      Exit(0);

    maxidx := Min(LASTIDX, smallidx + 8);
    minidx := maxidx - 8; // Often this equals smallidx

    // Assuming magicints is an external/global array
    smaller := magicints[Max(FIRSTIDX, smallidx-1)] div 2;
    smallnum := magicints[smallidx] div 2;
    sizesmall[0] := magicints[smallidx];
    sizesmall[1] := magicints[smallidx];
    sizesmall[2] := magicints[smallidx];
    larger := magicints[maxidx];

    // buf[0] holds the length in bytes
    if xdr_int(xdrs, buf[0]) = 0 then
      Exit(0);

    if xdr_opaque(xdrs, PChar(@buf[3]), buf[0]) = 0 then
      Exit(0);

    buf[0] := 0;
    buf[1] := 0;
    buf[2] := 0;

    lfp := fp;
    inv_precision := 1.0 / precision^;
    run := 0;
    i := 0;
    lip := ip;
  end;

  Result := 1;
end;


Please note the following:

You will need to adjust the constants (MAXID, FIRSTIDX, LASTIDX) as they were not provided in the original C code.
Some functions like xdr_int, xdr_vector, xdr_float, sizeofint, sizeofints, and the global arrays xdridptr, xdrmodes, and magicints are assumed to be available elsewhere, as they were referred to in the C code but not provided.
You might need to make adjustments based on your actual implementation and requirements.
This code was translated to the best of my understanding and may need adjustments for the actual purpose.


Извиняюсь за то, что спросил машину на вражеском, переспрашивать лень было.
Re[3]: Перевести код библиотеки xdr с C++ на Delphi
От: Khimik  
Дата: 24.10.23 14:58
Оценка:
Здравствуйте, Dimonka, Вы писали:

D>Да справляется GPT. Не греши за зря


K>>Первая половина:


Можно ещё вторую половину, раз уж начали?
"Ты должен сделать добро из зла, потому что его больше не из чего сделать". АБ Стругацкие.
Re: Перевести код библиотеки xdr с C++ на Delphi
От: BSOD  
Дата: 24.10.23 17:04
Оценка:
Здравствуйте, Khimik, Вы писали:

K>Мне надо перевести с C++ на Delphi фрагмент кода программы Gromacs, который читает файл с траекторией движения молекул.


Как уже советовали выше — прилинковать готовый код проще, или статически (lib), или динамически (dll).

При трансляции неизбежно трудноуловимых ошибок наделаешь...
Sine vilitate, sine malitiosa mente
Re[4]: Перевести код библиотеки xdr с C++ на Delphi
От: Dimonka Верблюд  
Дата: 25.10.23 08:27
Оценка: 1 (1)
Здравствуйте, Khimik, Вы писали:

K>>>Первая половина:


K>Можно ещё вторую половину, раз уж начали?


  Вторая половина
function xdr3dfcoord(xdrs: PXDR; fp: PSingle; var size: Integer; precision: PSingle): Integer;
const
  MAXID = ...;  // Define this value; it was not in the original code.
  FIRSTIDX = ...;  // Similarly, define this value.
var
  ip: PInteger = nil;
  oldsize: Integer;
  buf: PInteger;

  minint, maxint, lip, thiscoord, prevcoord: array[0..2] of Integer;
  mindiff, diff, lint1, lint2, lint3, oldlint1, oldlint2, oldlint3, smallidx: Integer;
  minidx, maxidx, flag, k, smallnum, smaller, larger, i, is_small, is_smaller: Integer;
  run, tmp, bufsize, xdrid, lsize: Integer;
  sizeint, sizesmall, bitsizeint: array[0..2] of Cardinal;
  size3: Cardinal;
  luip: PCardinal;
  lfp: PSingle;
  lf, inv_precision: Single;
  bitsize: Cardinal;
  errval: Integer = 1;
begin
  bitsizeint[0] := 0;
  bitsizeint[1] := 0;
  bitsizeint[2] := 0;
  prevcoord[0] := 0;
  prevcoord[1] := 0;
  prevcoord[2] := 0;

  xdrid := 0;
  while (xdridptr[xdrid] <> xdrs) do
  begin
    Inc(xdrid);
    if (xdrid >= MAXID) then
    begin
      WriteLn('xdr error. no open xdr stream');
      Halt(1);
    end;
  end;

  if (xdrmodes[xdrid] = 'w') or (xdrmodes[xdrid] = 'a') then
  begin
    // xdrs is open for writing – code skipped
  end
  else
  begin
    i := 0;
    while (i < lsize) do
    begin
      thiscoord := PInteger(lip) + i * 3;

      if (bitsize = 0) then
      begin
        thiscoord[0] := receivebits(buf, bitsizeint[0]);
        thiscoord[1] := receivebits(buf, bitsizeint[1]);
        thiscoord[2] := receivebits(buf, bitsizeint[2]);
      end
      else
      begin
        receiveints(buf, 3, bitsize, sizeint, thiscoord);
      end;

      Inc(i);
      Inc(thiscoord[0], minint[0]);
      Inc(thiscoord[1], minint[1]);
      Inc(thiscoord[2], minint[2]);

      prevcoord[0] := thiscoord[0];
      prevcoord[1] := thiscoord[1];
      prevcoord[2] := thiscoord[2];

      flag := receivebits(buf, 1);
      is_smaller := 0;
      if (flag = 1) then
      begin
        run := receivebits(buf, 5);
        is_smaller := run mod 3;
        Dec(run, is_smaller);
        Dec(is_smaller);
      end;

      if (run > 0) then
      begin
        Inc(thiscoord, 3);
        for k := 0 to run-1 do
        begin
          receiveints(buf, 3, smallidx, sizesmall, thiscoord);
          Inc(i);
          Inc(thiscoord[0], prevcoord[0] - smallnum);
          Inc(thiscoord[1], prevcoord[1] - smallnum);
          Inc(thiscoord[2], prevcoord[2] - smallnum);

          if (k = 0) then
          begin
            // interchange first with second atom for better compression of water molecules
            tmp := thiscoord[0];
            thiscoord[0] := prevcoord[0];
            prevcoord[0] := tmp;

            tmp := thiscoord[1];
            thiscoord[1] := prevcoord[1];
            prevcoord[1] := tmp;

            tmp := thiscoord[2];
            thiscoord[2] := prevcoord[2];
            prevcoord[2] := tmp;

            lfp^ := prevcoord[0] * inv_precision; Inc(lfp);
            lfp^ := prevcoord[1] * inv_precision; Inc(lfp);
            lfp^ := prevcoord[2] * inv_precision; Inc(lfp);
          end
          else
          begin
            prevcoord[0] := thiscoord[0];
            prevcoord[1] := thiscoord[1];
            prevcoord[2] := thiscoord[2];
          end;

          lfp^ := thiscoord[0] * inv_precision; Inc(lfp);
          lfp^ := thiscoord[1] * inv_precision; Inc(lfp);
          lfp^ := thiscoord[2] * inv_precision; Inc(lfp);
        end;
      end
      else
      begin
        lfp^ := thiscoord[0] * inv_precision; Inc(lfp);
        lfp^ := thiscoord[1] * inv_precision; Inc(lfp);
        lfp^ := thiscoord[2] * inv_precision; Inc(lfp);
      end;

      Inc(smallidx, is_smaller);
      if (is_smaller < 0) then
      begin
        smallnum := smaller;
        if (smallidx > FIRSTIDX) then
          smaller := magicints[smallidx - 1] div 2
        else
          smaller := 0;
      end
      else if (is_smaller > 0) then
      begin
        smaller := smallnum;
        smallnum := magicints[smallidx] div 2;
      end;

      sizesmall[0] := magicints[smallidx];
      sizesmall[1] := magicints[smallidx];
      sizesmall[2] := magicints[smallidx];
    end;
  end;

  Result := 1;
end;

Notes:

I'm assuming that PXDR, receivebits, receiveints, xdridptr, xdrmodes, and magicints are available elsewhere in your Delphi code as they were referred to in the C code but not provided.
The syntax for pointer arithmetic in Delphi is a little different from C. I've made adjustments accordingly.
Delphi uses div for integer division instead of /.
You'll need to define or replace MAXID, FIRSTIDX, and other constants and data types that were not provided in the original C code.
Some of the data structures and functions might need to be adjusted depending on the specifics of your Delphi implementation.
Always review and test the code thoroughly before integrating it into your project.


А ещё он привет тебе передавал, сказал завтра зайдёт.
...Шутка
Re[5]: Перевести код библиотеки xdr с C++ на Delphi
От: Dimonka Верблюд  
Дата: 25.10.23 09:20
Оценка:
Ну и чтобы ты ещё раз не просил

  Всё остальное
const
  BYTES_PER_XDR_UNIT = ...;  // Define this value, it was not provided in the original code.

type
  TXDROperation = (XDR_DECODE, XDR_ENCODE, XDR_FREE);

  PXDR = ^TXDR;
  TXDR = record
    x_op: TXDROperation;
    // ... other fields might be present, they were not provided in the C code.
  end;

function sizeofints(const num_of_ints: Integer; sizes: PCardinal): Integer;
var
  i, num, bytecnt: Integer;
  num_of_bytes, num_of_bits, tmp: Cardinal;
  bytes: array[0..31] of Cardinal;
begin
  num_of_bytes := 1;
  bytes[0] := 1;
  num_of_bits := 0;
  for i := 0 to num_of_ints - 1 do
  begin
    tmp := 0;
    bytecnt := 0;
    while bytecnt < num_of_bytes do
    begin
      tmp := bytes[bytecnt] * sizes[i] + tmp;
      bytes[bytecnt] := tmp and $FF;
      tmp := tmp shr 8;
      Inc(bytecnt);
    end;
    while tmp <> 0 do
    begin
      bytes[bytecnt] := tmp and $FF;
      tmp := tmp shr 8;
      Inc(bytecnt);
    end;
    num_of_bytes := bytecnt;
  end;
  num := 1;
  Dec(num_of_bytes);
  while bytes[num_of_bytes] >= num do
  begin
    Inc(num_of_bits);
    num := num * 2;
  end;
  Result := num_of_bits + num_of_bytes * 8;
end;

function receivebits(buf: PInteger; num_of_bits: Integer): Integer;
var
  cnt, mask, num: Integer;
  lastbits, lastbyte: Cardinal;
  cbuf: PByte;
begin
  cbuf := PByte(buf) + 3 * SizeOf(buf^);
  cnt := buf[0];
  lastbits := Cardinal(buf[1]);
  lastbyte := Cardinal(buf[2]);

  num := 0;
  while num_of_bits >= 8 do
  begin
    lastbyte := (lastbyte shl 8) or cbuf[cnt];
    Inc(cnt);
    num := num or ((lastbyte shr lastbits) shl (num_of_bits - 8));
    Dec(num_of_bits, 8);
  end;

  if num_of_bits > 0 then
  begin
    if lastbits < num_of_bits then
    begin
      lastbits := lastbits + 8;
      lastbyte := (lastbyte shl 8) or cbuf[cnt];
      Inc(cnt);
    end;
    Dec(lastbits, num_of_bits);
    num := num or ((lastbyte shr lastbits) and ((1 shl num_of_bits) - 1));
  end;
  mask := (1 shl num_of_bits) - 1;
  num := num and mask;
  buf[0] := cnt;
  buf[1] := Integer(lastbits);
  buf[2] := Integer(lastbyte);
  Result := num;
end;

procedure receiveints(buf: PInteger; const num_of_ints, num_of_bits: Integer; sizes: PCardinal; nums: PInteger);
var
  bytes: array[0..31] of Integer;
  i, j, num_of_bytes, p, num: Integer;
begin
  bytes[1] := 0;
  bytes[2] := 0;
  bytes[3] := 0;
  num_of_bytes := 0;
  while num_of_bits > 8 do
  begin
    bytes[num_of_bytes] := receivebits(buf, 8);
    Inc(num_of_bytes);
    Dec(num_of_bits, 8);
  end;

  if num_of_bits > 0 then
  begin
    bytes[num_of_bytes] := receivebits(buf, num_of_bits);
    Inc(num_of_bytes);
  end;

  for i := num_of_ints - 1 downto 1 do
  begin
    num := 0;
    for j := num_of_bytes - 1 downto 0 do
    begin
      num := (num shl 8) or bytes[j];
      p := num div sizes[i];
      bytes[j] := p;
      num := num - p * sizes[i];
    end;
    nums[i] := num;
  end;
  nums[0] := bytes[0] or (bytes[1] shl 8) or (bytes[2] shl 16) or (bytes[3] shl 24);
end;

function xdr_opaque(xdrs: PXDR; cp: PAnsiChar; cnt: Cardinal): Boolean;
var
  rndup: Cardinal;
  crud: array[0..BYTES_PER_XDR_UNIT - 1] of AnsiChar;
begin
  Result := True;
  if cnt = 0 then
    Exit;

  rndup := cnt mod BYTES_PER_XDR_UNIT;
  if rndup > 0 then
    rndup := BYTES_PER_XDR_UNIT - rndup;

  case xdrs^.x_op of
    XDR_DECODE:
      begin
        if not xdr_getbytes(xdrs, cp, cnt) then
          Result := False
        else if rndup = 0 then
          Result := True
        else
          Result := xdr_getbytes(xdrs, crud, rndup);
      end;
    XDR_ENCODE:
      begin
        if not xdr_putbytes(xdrs, cp, cnt) then
          Result := False
        else if rndup = 0 then
          Result := True
        else
          Result := xdr_putbytes(xdrs, xdr_zero, rndup);  // Assuming xdr_zero is defined elsewhere in your code
      end;
    XDR_FREE:
      Result := True;
  else
    Result := False;
  end;
end;


Notes:

I have made certain assumptions about data structures (TXDR, etc.) and functions (xdr_getbytes, xdr_putbytes, etc.) because they were referred to in the C code but not provided. You may need to adjust accordingly based on your actual definitions and requirements.
PAnsiChar is used instead of char* in Delphi. It's assumed the char in your C code refers to an 8-bit character.
You should thoroughly review and test this translation to ensure correctness and compatibility with your Delphi environment and project requirements.

Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.