如何在类型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;