如何定义一个A型在A型B型和B型? [英] How to define a Type A in Type B and Type B in Type A?

查看:140
本文介绍了如何定义一个A型在A型B型和B型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

 键入
    的typeA =记录
       测试1:TYPEB;
    结束;
  类型
    TYPEB =记录
       测试2:的typeA;
    结束;

编辑:
那不是我的设计。我转换C头文件(访问DLL),其中包括这样的结构来德尔福。

EDIT2:
C ++结构是类AFAIR另一个名称,一定有指针,而不是值本身。 - 亚略的1分钟前
是的,你是对的,这是一个指向一个类型:

有我definied:

 测试1:^ TYPEB;

请问这项工作呢?

 测试1:指针;

EDIT3:
在C结构:

  / * * DLPDFPAGE /
typedef结构dlpdfpage
{
    CosObj页;
    CosObj PrintSelect;
    ASFixedRect PageBBox;
    ASFixedRect ContentBBox;
    结构dlpdfpage *下一步;
    PDRotate角;
    结构dlpdfdoc *文件;
    DLPDFSTREAM *内容;
    长的PageNumber;
    烧焦完成;
    焦炭FontSubstituted;
    焦炭FontMM;
    焦炭FontBad;
} DLPDFPAGE;
/ * * DLPDFDOC /
typedef结构dlpdfdoc
{
    DLPDFINSTANCE * dliInstance;
    PDDoc pdDoc;
    CosDoc cosDoc;
    DLPDFOUTLINE *纲要;
    字符* PDFFileName;
    字符* PDFPostFileName;
    DLPOS LastPageEnd;
    DLPOS BeforeDef;
    ASFixedRect DocBBox;
    长页页次;
    长PageTreeWidth;
    长PageTreeDepth;
    长PageTreeDepthUsed;
    DLPDFPAGETREEARRAY *所有页;
    DLPDFFONTLIST * AllFonts;
    DLPDFFORMLIST * AllForms;
    DLPDFFORMLIST * AllColors;
    DLPDFIMAGELIST * AllImages;
    DLPDFSPOTCOLORLIST * AllSpotColors;
    DLPDFSPOTCOLORLIST * AllPatterns;
    DLPDFEXTGSTATELIST * AllExtGStates;
    DLPDFPAGE *分页;
    DLPDFPAGE *尾;
    DLPDFDEST * DeferedDests;
    DLPDFSIGNATURE * signatureHolder;
    结构dlpdfacroform * AcroFormBase;
    CosObj PatternColorObj,
                        PatternColorRGBObj,
                        PatternColorCMYKObj,
                        PatternColorGrayObj,
            PrintSelect,
            PrintSelectCriteria;
    CosObj IdentH,IdentV;
    ASAtom DocumentEncoding;
    长FontCount;
    长FormCount;
    长PatCount;
    长ImageCount;
    焦炭的COM preSS;
    焦炭线性化;
    焦炭PageTreeComplete;
    焦炭的embedFonts;
    焦炭PatternColorsDefined;
    焦炭MakeThumbNails;
    ASBool psSevenBitSafe;
    ASInt32 EncryptKeyByteCount;    焦炭condenseResDicts;
    CosObj resourceDict;    ASInt16 pdfMajorVer;
    ASInt16 pdfMinorVer;    DLPDFINCLUDEDRES * InclRes;    DLPDFSPOTCOLORLIST * AllShadings;
    长ShadeCount;} DLPDFDOC;


解决方案

您误解了这些C结构重新present。这是因为,记录是值类型的:它存储在那里,你声明变量。因此,让我们做递归声明的几级,你就会明白我的意思;假设这两种结构都没有绝对相同的:

 键入
  TA =记录
     测试1:TB;
     SomethingElseFromA:字节;
  结束;  TB =记录
     测试2:TA;
     SomethingElseFromB:字节;
  结束;

结构 TA 可以改写的意思是:

 键入
  TA =记录
    //替换测试1:结核病结核病的实际内容,因为这是
    //记录是什么意思。
    test1_test2:TA;
    test1_SomethingElseFromB:字节;    SomethingElseFromA:字节;
  结束;

当然,我们现在已经有了一个很好的递归纳入自我到 TA 记录,沿着线的东西:

  TA =记录
    //替换test1_test:TA
    test1_test2:TA; //哎呀,依然不动,需要重新做...
    test1_SomethingElseFromB:字节;
    SomethingElseFromA:字节;    test1_SomethingElseFromB:字节;
    SomethingElseFromA:字节;
  结束;

您可能需要使用引用类型得到的东西看起来相似,但它并不相似。引用类型始终是一个指针,所以这是一个固定的大小;编译器可以毫无问题分配它。这将是有效的,使用指针到记录:

 键入
  pTypeB = ^ TYPEB;
  pTypeA = ^的typeA;  的typeA =记录
     测试1:pTypeB;
  结束;  TYPEB =记录
     测试2:pTypeA;
  结束;

另外,您可以使用类;这适用于同样的原因,类是引用类型;他们的工作方式为指针一样。当你声明的指针型,编译器分配中SizeOf(指针)字节的变量


既然你已经发布的C结构,我可以告诉他们太长时间,我尝试一个完整的翻译,但我可以提出几点建议:你应该在一个键入块;每种类型的声明之前不写键入。这可以让你记录类型之前创建的指针类型,就像这样:

 键入
  PMyRecord = ^ TMyRecord;  //某处在同一类型的块
  TMyRecord =记录
  结束;

有关要求指针到记录每种类型,声明指针第一件事键入关键字,它更简单后的方式。接下来,你需要确定C指针。如果有一个 * 的数据类型的名称和字段的名称之间,这是一个指针。这通常是这样写的:

 为int * PointerToSomeInt;

但这些将是一种有效的:

 为int * PointerToSomeInt;
为int * VarName1,* VarName1,* VarName3; //三分为整数。

最后,你需要处理的调整问题。如果可以的话,请检查C面结构的大小,然后检查德尔福端大小:你应该得到相同的大小。如果不这样做,你应该尝试一对夫​​妇随机 {$ ALIGN} 编译器指令的结构声明之前,重复,直到你罢工的正确路线。如果一切都失败,你需要找到什么是错的(是在Delphi的不同侧面对准哪些字段),并把一些字节对齐人为地修复它。

I have two types. One Type A and one Type B. The Problem Type A contains Type B and Type B contains Type A. Such a thing like this won't work:

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

Edit: Thats not my design. I converting C Header files (to access a DLL) that include such constructs to delphi.

Edit2: "C++ structs are another name for classes AFAIR. And there must have been pointers, not values themselves. – Arioch 'The 1 min ago" Yes you are right that was a Pointer to a Type:

There I definied:

test1 : ^typeB;

Will that work instead?

test1 : Pointer;

Edit3: The C Structs:

/* 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;

解决方案

You misunderstood what those C structs represent. That's because a record is a value type: it's stored right there where you declare the variable. So let's do a few levels of recursive declarations, and you'll understand what I mean; Assuming the two structures aren't absolutely identical:

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

  TB = record
     test2 : TA;
     SomethingElseFromB: Byte;
  end;   

Structure TA could be rewritten to mean this:

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;

Of course, we've now got a nice recursive inclusion of self into the TA record, something along the lines of:

  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;

You probably want to use reference types to get something that looks similar, but it's not similar. A reference type is always a pointer, so it's a fixed size; The compiler can allocate it without a problem. This would be valid, using pointers-to-records:

type
  pTypeB = ^typeB;
  pTypeA = ^typeA;

  typeA = record
     test1 : pTypeB;
  end;

  typeB = record
     test2 : pTypeA;
  end;

Alternatively you could use classes; That works for the same reason, classes are reference types; they work the same way as pointers. When you declare a variable of pointer-type, the compiler allocates SizeOf(Pointer) bytes.


Since you've posted the C structs, I can tell they're too long for me to attempt a complete translation, but I can make a few suggestions: You should declare all your types in a single Type block; don't write the Type before each type declaration. This allows you to create the pointer type before the record type, like this:

Type
  PMyRecord = ^TMyRecord;

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

For each type that requires pointers-to-records, declare the pointers first thing after the Type keyword, it's simpler that way. Next, you need to identify the C pointers. If there's a * between the name of the data type and the name of the field, that's a pointer. This is usually written like this:

int *PointerToSomeInt;

But those would be just as valid:

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

Finally, you'll need to deal with alignment issues. If you can, check the size of the structures on the C side, and then check the size on the Delphi side: you should get the same size. If you don't, you should try a couple of random {$ALIGN} compiler directives before your structure declaration and repeat until you strike the correct alignment. If all else fails you'll need to find what's wrong (what fields are aligned differently on the Delphi side) and put in some alignment bytes to artificially fix it.

这篇关于如何定义一个A型在A型B型和B型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆