如何在类型A中定义类型B中的类型A和类型B中的类型B?

我有两种类型。 一个类型A和一个类型B.问题类型A包含类型B,类型B包含类型A.这样的事情将不起作用:

type typeA = record test1 : typeB; end; type typeB = record test2 : typeA; end; 

编辑:那不是我的设计。 我将包含此类构造的C头文件(访问DLL)转换为delphi。

编辑2: “C ++结构是类AFAIR的另一个名称。并且必须有指针,而不是值本身。 – Arioch’1分钟之前”是的你是对的,它是一个类型的指针:

我在那里定义:

 test1 : ^typeB; 

这会改变吗?

 test1 : Pointer; 

Edit3: C结构:

 /* DLPDFPAGE */ typedef struct dlpdfpage { CosObj Page; CosObj PrintSelect; ASFixedRect PageBBox; ASFixedRect ContentBBox; struct dlpdfpage *Next; PDRotate Angle; struct dlpdfdoc *Doc; DLPDFSTREAM *Content; long PageNumber; char Complete; char FontSubstituted; char FontMM; char FontBad; } DLPDFPAGE; /* DLPDFDOC */ typedef struct dlpdfdoc { DLPDFINSTANCE *dliInstance; PDDoc pdDoc; CosDoc cosDoc; DLPDFOUTLINE *Outlines; char *PDFFileName; char *PDFPostFileName; DLPOS LastPageEnd; DLPOS BeforeDef; ASFixedRect DocBBox; long PageCount; long PageTreeWidth; long PageTreeDepth; long PageTreeDepthUsed; DLPDFPAGETREEARRAY *AllPages; DLPDFFONTLIST *AllFonts; DLPDFFORMLIST *AllForms; DLPDFFORMLIST *AllColors; DLPDFIMAGELIST *AllImages; DLPDFSPOTCOLORLIST *AllSpotColors; DLPDFSPOTCOLORLIST *AllPatterns; DLPDFEXTGSTATELIST *AllExtGStates; DLPDFPAGE *PageList; DLPDFPAGE *LastPage; DLPDFDEST *DeferedDests; DLPDFSIGNATURE *signatureHolder; struct dlpdfacroform *AcroFormBase; CosObj PatternColorObj, PatternColorRGBObj, PatternColorCMYKObj, PatternColorGrayObj, PrintSelect, PrintSelectCriteria; CosObj IdentH, IdentV; ASAtom DocumentEncoding; long FontCount; long FormCount; long PatCount; long ImageCount; char Compress; char Linearize; char PageTreeComplete; char EmbedFonts; char PatternColorsDefined; char MakeThumbNails; ASBool psSevenBitSafe; ASInt32 EncryptKeyByteCount; char condenseResDicts; CosObj resourceDict; ASInt16 pdfMajorVer; ASInt16 pdfMinorVer; DLPDFINCLUDEDRES *InclRes; DLPDFSPOTCOLORLIST *AllShadings; long ShadeCount; } DLPDFDOC; 

你误解了那些C结构代表的东西。 这是因为record是一种值类型:它存储在您声明变量的位置。 那么让我们做一些级别的递归声明,你就会理解我的意思; 假设两个结构不完全相同:

 type TA = record test1 : TB; SomethingElseFromA: Byte; end; TB = record test2 : TA; SomethingElseFromB: Byte; end; 

结构TA可以改写为:

 type TA = record // Replaced test1 : TB with the actual content of TB, because that's // what a record means. test1_test2: TA; test1_SomethingElseFromB: Byte; SomethingElseFromA: Byte; end; 

当然,我们现在有一个很好的递归包含自我进入TA记录,有点类似于:

  TA = record // Replaces test1_test: TA test1_test2: TA; // Oops, still not fixed, need to do it again... test1_SomethingElseFromB: Byte; SomethingElseFromA: Byte; test1_SomethingElseFromB: Byte; SomethingElseFromA: Byte; end; 

您可能希望使用引用类型来获得看起来相似的内容,但它并不相似。 引用类型始终是指针,因此它是固定大小; 编译器可以毫无问题地分配它。 这将是有效的,使用指针记录:

 type pTypeB = ^typeB; pTypeA = ^typeA; typeA = record test1 : pTypeB; end; typeB = record test2 : pTypeA; end; 

或者你可以使用类; 这也是出于同样的原因,类是引用类型; 它们的工作方式与指针相同。 声明指针类型的变量时,编译器会分配SizeOf(Pointer)字节。


既然你已经发布了C结构,我可以说它们对我来说太长了以后尝试完整的翻译,但我可以提出一些建议:你应该在一个Type块中声明所有类型; 不要在每个类型声明之前写入Type 。 这允许您在记录类型之前创建指针类型,如下所示:

 Type PMyRecord = ^TMyRecord; // Somewhere in the same Type block TMyRecord = record end; 

对于每个需要指针到记录的Type ,在Type关键字之后首先声明指针,这样就更简单了。 接下来,您需要识别C指针。 如果数据类型的名称和字段名称之间有* ,那就是指针。 这通常是这样写的:

 int *PointerToSomeInt; 

但那些都是有效的:

 int * PointerToSomeInt; int* VarName1, * VarName1, * VarName3; // Three pointers to integer. 

最后,您需要处理对齐问题。 如果可以的话,检查C侧结构的大小,然后检查Delphi侧的大小:你应该得到相同的大小。 如果不这样做,您应该在结构声明之前尝试几个随机的{$ALIGN}编译器指令,并重复直到找到正确的对齐方式。 如果所有其他方法都失败了,你需要找到什么是错的(在Delphi端哪些字段的排列方式不同)并加入一些对齐字节来人工修复它。

也许最好的解决方案是重新考虑设计。 但您可能也对所谓的类的前向声明感兴趣:

 type TTypeB = class; TTypeA = class test: TTypeB; end; TTypeB = class test: TTypeA; end; 

SIC! 这仅适用于类,而不适用于记录。

您显示的C代码的Delphi转换如下所示:

 type DLPDFDOC = record; // forward declaration { DLPDFPAGE } DLPDFPAGE = record Page: CosObj; PrintSelect: CosObj; PageBBox: ASFixedRect; ContentBBox: ASFixedRect; Next: ^DLPDFPAGE; Angle: PDRotate; Doc: ^DLPDFDOC; Content: ^DLPDFSTREAM; PageNumber: Longint; Complete: AnsiChar; FontSubstituted: AnsiChar; FontMM: AnsiChar; FontBad: AnsiChar; end; { DLPDFDOC } DLPDFDOC = record dliInstance: ^DLPDFINSTANCE; pdDoc: PDDoc; cosDoc: CosDoc; Outlines: ^DLPDFOUTLINE; PDFFileName: PAnsiChar; PDFPostFileName: PAnsiChar; LastPageEnd: DLPOS; BeforeDef: DLPOS; DocBBox: ASFixedRect; PageCount: Longint; PageTreeWidth: Longint; PageTreeDepth: Longint; PageTreeDepthUsed: Longint; AllPages: ^DLPDFPAGETREEARRAY; AllFonts: ^DLPDFFONTLIST; AllForms: ^DLPDFFORMLIST; AllColors: ^DLPDFFORMLIST; AllImages: ^DLPDFIMAGELIST; AllSpotColors: ^DLPDFSPOTCOLORLIST; AllPatterns: ^DLPDFSPOTCOLORLIST; AllExtGStates: ^DLPDFEXTGSTATELIST; PageList: ^DLPDFPAGE; LastPage: ^DLPDFPAGE; DeferedDests: ^DLPDFDEST; signatureHolder: ^DLPDFSIGNATURE; AcroFormBase: ^DLPDFACROFORM; PatternColorObj: CosObj; PatternColorRGBObj: CosObj; PatternColorCMYKObj: CosObj; PatternColorGrayObj: CosObj; PrintSelect: CosObj; PrintSelectCriteria: CosObj; IdentH: CosObj; IdentV: CosObj; DocumentEncoding: ASAtom; FontCount: Longint; FormCount: Longint; PatCount: Longint; ImageCount: Longint; Compress: AnsiChar; Linearize: AnsiChar; PageTreeComplete: AnsiChar; EmbedFonts: AnsiChar; PatternColorsDefined: AnsiChar; MakeThumbNails: AnsiChar; psSevenBitSafe: ASBool; EncryptKeyByteCount: ASInt32; condenseResDicts: AnsiChar; resourceDict: CosObj; pdfMajorVer: ASInt16; pdfMinorVer: ASInt16; InclRes: ^DLPDFINCLUDEDRES; AllShadings: ^DLPDFSPOTCOLORLIST; ShadeCount: Longint; end;