将 C 联合翻译成 Pascal 变体记录
Translate C union to pascal variant record
帮一个n00b出来!
我正在为 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;
我觉得不对的地方:
- 首先它的错误是可变记录在不同的位置,但在 Pascal 中它只能放在记录的末尾。
- 变异记录被错误申报。
我向#fpc 频道寻求了一些帮助,他们指出的两个可能的变体是制作两条记录(一个只有变体记录),第二个是使用这个 case 语句。最后一个选项应该是最兼容的。
我以前没有在 Pascal 中使用这种语句的经验,所以有人可以解释一下它是如何工作的吗?
谢谢!
第一个通常通过将联合之后的字段移动到联合的一个分支来解决,如下例所示,但这在这里不起作用,因为联合不是匿名的。
未经测试的快速重排:
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以u为前缀。
Gboolean 应该在 gtk/glib headers 中声明,当然打包仍然会搞砸。
所以我使用 Marco van de Voort 的代码并对其进行了一些修改 - 也许有人会觉得它对这里有帮助。
{$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 来推动它。
感谢您的帮助!
帮一个n00b出来!
我正在为 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;
我觉得不对的地方:
- 首先它的错误是可变记录在不同的位置,但在 Pascal 中它只能放在记录的末尾。
- 变异记录被错误申报。
我向#fpc 频道寻求了一些帮助,他们指出的两个可能的变体是制作两条记录(一个只有变体记录),第二个是使用这个 case 语句。最后一个选项应该是最兼容的。
我以前没有在 Pascal 中使用这种语句的经验,所以有人可以解释一下它是如何工作的吗?
谢谢!
第一个通常通过将联合之后的字段移动到联合的一个分支来解决,如下例所示,但这在这里不起作用,因为联合不是匿名的。
未经测试的快速重排:
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以u为前缀。
Gboolean 应该在 gtk/glib headers 中声明,当然打包仍然会搞砸。
所以我使用 Marco van de Voort 的代码并对其进行了一些修改 - 也许有人会觉得它对这里有帮助。
{$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 来推动它。
感谢您的帮助!