我有两种类型。一个类型A和一个类型B.问题类型A包含类型B而类型B包含类型A.这样的事情不会起作用:
type
typeA = record
test1 : typeB;
end;
type
typeB = record
test2 : typeA;
end;
修改 那不是我的设计。我将包含此类构造的C头文件(访问DLL)转换为delphi。
EDIT2: " 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;
答案 0 :(得分:14)
你误解了那些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
关键字之后首先声明指针,这样就更简单了。接下来,您需要识别C指针。如果数据类型的名称和字段名称之间有*
,那就是指针。这通常是这样写的:
int *PointerToSomeInt;
但那些也同样有效:
int * PointerToSomeInt;
int* VarName1, * VarName1, * VarName3; // Three pointers to integer.
最后,您需要处理对齐问题。如果可以的话,检查C侧结构的大小,然后检查Delphi侧的大小:你应该得到相同的大小。如果不这样做,则应在结构声明之前尝试使用几个随机{$ALIGN}
编译器指令,然后重复执行,直到找到正确的对齐方式。如果所有其他方法都失败了,你需要找到错误的东西(在Delphi方面哪些字段的排列方式不同)并加入一些对齐字节来人工修复它。
答案 1 :(得分:11)
也许最好的解决方案是重新考虑设计。但您可能也对类的所谓前向声明感兴趣:
type
TTypeB = class;
TTypeA = class
test: TTypeB;
end;
TTypeB = class
test: TTypeA;
end;
SIC!这仅适用于类,而不适用于记录。
答案 2 :(得分:1)
您展示的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;