如何在B类中定义A类,在A类中定义B类?

2023-11-25

我有两种类型。一种类型 A 一种类型 B。问题类型 A 包含类型 B,类型 B 包含类型 A。这样的事情是行不通的:

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

Edit:那不是我的设计。我将包含此类构造的 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;

您误解了那些 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;

当然,我们现在已经很好地将 self 递归包含到了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) bytes.


由于您已经发布了 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 端的对齐方式不同)并放入一些对齐字节来人为地修复它。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在B类中定义A类,在A类中定义B类? 的相关文章

随机推荐