Преобразование сложной структуры / opaquepointer / function из заголовка C ++ в Delphi - PullRequest
0 голосов
/ 28 февраля 2019

Я конвертирую из заголовка C / C ++ в Delphi.Я внимательно прочитал замечательную статью Rudy's Delphi Corner об этом виде преобразования.В любом случае, я сталкиваюсь с чем-то, что мне трудно понять.

Там есть непрозрачный указатель, затем прототип функции, у которого этот указатель является параметром, за которым следует объявление структуры og типа функции.

Возможно, код прояснит ситуацию.

исходный код .h:

struct my_ManagedPtr_t_;
typedef struct my_ManagedPtr_t_ my_ManagedPtr_t;

typedef int (*my_ManagedPtr_ManagerFunction_t)(
                                            my_ManagedPtr_t *managedPtr,
                                            const my_ManagedPtr_t *srcPtr,
                                            int operation);

typedef union {
    int   intValue;
    void *ptr;
} my_ManagedPtr_t_data_;

struct my_ManagedPtr_t_ {
    void *pointer;
    my_ManagedPtr_t_data_ userData[4];
    my_ManagedPtr_ManagerFunction_t  manager;
};

typedef struct my_CorrelationId_t_ {
    unsigned int  size:8;       // fill in the size of this struct
    unsigned int  valueType:4;  // type of value held by this correlation id
    unsigned int  classId:16;   // user defined classification id
    unsigned int  reserved:4;   // for internal use must be 0

    union {
        my_UInt64_t      intValue;
        my_ManagedPtr_t  ptrValue;
    } value;
} my_CorrelationId_t;

... я потерян.:-( Я не могу понять, с чего начать. Структура? Функция?

Спасибо.

Ответы [ 2 ]

0 голосов
/ 28 февраля 2019

Немного сложно определить, с чего начать, но объяснение @ DavidHeffernan о форвардном объявлении типа указателя должно дать вам начало.

Я бы перевел это на следующее ( непроверено ) код:

type
  _my_ManagedPtr_p = ^my_ManagedPtr_t;

  my_ManagedPtr_ManagerFunction_t = function(
    managedPtr: my_ManagedPtr_p;
    scrPtr: my_ManagedPtr_p; 
    operation: Integer): Integer cdecl;

  my_ManagedPtr_t_data = record
    case Boolean of
      False: (intValue: Integer);
      True:  (ptr: Pointer);
  end;

  my_ManagedPtr_t = record
    ptr: Pointer;
    userData: array[0..3] of my_ManagedPr_t_data;
    manager: my_ManagedPtr_ManagerFunction_t;
  end;

  my_CorrelationId_t = record
    typeData: UInt32; // size, valueType, classId and reserved combined in one integer.
    case Byte of
       0: (intValue: my_UInt64_t);
       1: (ptrValue: my_ManagedPtr_t;
  end;

Я не собираюсь делать битовые поля, но, пожалуйста, прочитайте раздел Битовые поля моей статьи Подводные камни преобразования снова (я вижуВы уже упоминали это), чтобы найти несколько решений.Если вы хотите сделать это действительно хорошо, используйте методы и индексированный доступ, в противном случае просто используйте сдвиги и маски для доступа к битовым полям, содержащимся в элементе, который я назвал typeData.Как это можно сделать, объясняется в статье, и здесь слишком много повторений.

Если у вас все равно есть проблемы, задайте новый вопрос.

0 голосов
/ 28 февраля 2019

Как вы пояснили в комментариях, ближайшая область путаницы для вас - это круговая ссылка.Параметры указателя на функцию ссылаются на структуру, но структура содержит указатель на функцию.В коде C это решается непрозрачным объявлением типа структуры, которое является просто предварительным объявлением.Предварительное объявление просто обещает, что тип будет полностью объявлен на более позднем этапе.

В Delphi вы можете справиться с этим прямо аналогичным образом.Вам нужно использовать прямое объявление типа.Я не хочу переводить все типы в вашем вопросе, потому что это потребовало бы иметь дело с объединениями и битовыми полями, которые я считаю отдельными темами.Вместо этого я представлю простой пример Delphi, который показывает, как обращаться с такими циклическими объявлениями типов.Вы можете взять концепцию и применить ее к вашим конкретным типам.

type
  PMyRecord = ^TMyRecord; // forward declaration
  TMyFunc = function(rec: PMyRecord): Integer; cdecl;
  TMyRecord = record
    Func: TMyFunc;
  end;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...