帮个忙!
我正在为一个C库编写绑定,遇到了union声明/变量记录。我试图让它工作,但没有运气。
原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;

我觉得有什么问题:
它的第一个错误是varaiant记录位于不同的位置,但是在Pascal中,它只能放在记录的末尾。
变量记录被错误声明。
我向fpc频道寻求了一些帮助,他们指出的两个可能的变体是创建两个记录(其中一个只包含变体记录),第二个是使用这个case语句。最后一个选项应该是最兼容的。
我以前没有用帕斯卡语写这种陈述的经验,所以有人能解释一下这是如何工作的吗?
谢谢!

最佳答案

第一个通常是通过将联合之后的字段移动到联合的一个分支(如下面的示例中所示)来修复的,但这在这里不起作用,因为联合不是匿名的。
未经测试的快速重新排列:

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
但这需要用户界面操作在消息历史记录前加上u。
Gboolean应该在gtk/glib报头中声明,当然打包仍然可能会弄糟这一点。

关于c - 将C并集转换为Pascal变体记录,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31745629/

10-14 22:09
查看更多