7

私は2つのタイプを持っています。1 つのタイプ A と 1 つのタイプ 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;
4

3 に答える 3

14

これらの C 構造体が表すものを誤解しています。これrecordは、 a が値型であるためです。変数を宣言した場所に格納されます。それでは、いくつかのレベルの再帰宣言を行いましょう。そうすれば、私の言いたいことが理解できるでしょう。2 つの構造が完全に同一ではないと仮定すると、次のようになります。

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ような行に沿って、レコードに self を再帰的に含めることができます。

  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 構造体を投稿したので、完全な翻訳を試みるには長すぎることがわかりますが、いくつかの提案をすることができます: すべての型を 1 つの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 側で異なって整列されているのか) を見つけ、人為的に修正するためにいくつかの整列バイトを挿入する必要があります。

于 2013-01-21T11:38:11.003 に答える
11

おそらく最善の解決策は、設計を再考することです。しかし、いわゆるクラスの前方宣言にも興味があるかもしれません。

type
  TTypeB = class;

  TTypeA = class
    test: TTypeB;
  end;

  TTypeB = class
    test: TTypeA;
  end;      

シッ!これは、レコードではなく、クラスに対してのみ機能します。

于 2013-01-21T11:20:12.547 に答える
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;
于 2013-01-21T20:30:36.717 に答える