2015-07-31 5 views
1

Помогите n00b!Перевести C union to pascal вариант записи

Я пишу привязки для библиотеки C, и я наткнулся на декларацию о союзе/вариант записи. Я пытался заставить его работать, но не повезло.

Оригинальный код C:

struct _PurpleConversation 
{ 
    PurpleConversationType type; 
    PurpleAccount *account;  
    char *name;     
    char *title; 
    gboolean logging; 
    GList *logs;     
    union 
    { 
     PurpleConvIm *im; 
     PurpleConvChat *chat; 
     void *misc; 
    } u; 
    PurpleConversationUiOps *ui_ops; 
    void *ui_data; 
    GHashTable *data; 
    PurpleConnectionFlags features; 
    GList *message_history; 
}; 

Мой перевод:

TPurpleConversation = record 
    convtype : TPurpleConversationType; 
    account: PPurpleAccount; 
    name : PChar; 
    title: PChar; 
    logging: Boolean32; 
    logs: PGlist; 
    ui_ops: TPurpleConversationUiOps; 
    ui_data : Pointer; 
    data: PGHashTable;      
    features : TPurpleMessageFlags; 
    message_history : PGList;   

    case u : integer of 
    0:(
     im: PPurpleConversationIm;   
     chat: PPurpleConversationChat; 
     misc: Pointer; 
    ); 
end; 

То, что я думаю, что это неправильно с этим:

  • Первое, что является неправильно с ним заключается в том, что запись varayant находится в другом месте, но в Pascal ее можно разместить только в конце записи.
  • Вариант записи ложно объявлен.

Я попросил некоторую помощь от канала #fpc, и два возможных варианта, на которые они указывали, состоят в том, чтобы сделать две записи (одну с только записью варианта), а вторая - использовать этот оператор case. Последний вариант должен быть наиболее совместимым.

У меня нет предыдущего опыта с этим заявлением в Паскале, так что кто-нибудь может объяснить, как это работает?

Спасибо!

+0

Вы читали описание с типичными примерами (http://docwiki.embarcadero.com/RADStudio/XE3/en/Structured_Types#Variant_Parts_in_Records)? Если да, можете ли вы добавить более подробную информацию о проблеме? – Ilya

+0

Это не работает и выдает сбой хост-приложение, и, на мой взгляд, проблема в том, что запись не является тем, что ожидает библиотека C. – Klamberext

ответ

0

Итак, я получил это, используя код Марко ван де Воорта и немного его изменив - может быть, кто-то сочтет это полезным здесь.

{$packrecords C} 
TPurpleConversation = record 
    convtype : TPurpleConversationType; 
    account: PPurpleAccount; 
    name : PChar; 
    title: PChar; 
    logging: GBoolean; 
    logs: PGlist; 

    case longint of 
     0 : (im : PPurpleConversationIm); 
     1 : (chat : PPurpleConversationChat); 
     2 : (misc : Pointer; 
      ui_ops: TPurpleConversationUiOps; 
      ui_data : Pointer; 
      data: PGHashTable;      
      features : TPurpleMessageFlags; 
      message_history : PGList;   
     ); 
end; 

Что было сделано:

  • Добавлена ​​директива выравнивания байт {$ packrecords C}.
  • Удалено тегом из варианта записи.

Это позволило мне продолжить и использовать этот объект как параметр функции и т. Д., И все было хорошо. Но есть и другие проблемы с привязкой, которые просто не стоят усилий, поэтому я сбросил FreePascal для этого проекта и начал нажимать его на C.

Спасибо за помощь!

2

Первый обычно фиксируется перемещением полей после объединения в одну из ветвей объединения, как в приведенном ниже примере, но это не будет работать, потому что объединение не является анонимным.

Непроверено быстро перегруппировка:

TPurpleConversation = record 
    convtype : TPurpleConversationType; 
    account: PPurpleAccount; 
    name : PChar; 
    title: PChar; 
    logging: Boolean32; 
    logs: PGlist; 
    case u : integer of 
    0:(im: PPurpleConversationIm; ); 
    1: (chat: PPurpleConversationChat;); 
    2: ( misc: Pointer;  
      ui_ops: TPurpleConversationUiOps; 
      ui_data : Pointer; 
      data: PGHashTable;      
      features : TPurpleMessageFlags; 
      message_history : PGList;   
    ); 
end; 

Синтаксис можно узнать из документации: http://www.freepascal.org/docs-html/ref/refsu19.html

, но это требует, чтобы ui_ops message_history быть с приставкой и.

Gboolean должен быть объявлен в заголовках gtk/glib, и, конечно, упаковка все равно может испортиться.

+0

Да, теперь я изменил тип Boolean - PGBoolean. – Klamberext

 Смежные вопросы

  • Нет связанных вопросов^_^