开发者

C#: How to access an unmanaged, 2-Dbinary array nested in a struct?

开发者 https://www.devze.com 2023-03-16 09:34 出处:网络
PROBLEM: I\'m trying access binary records that were created in Borland Delphi and stored in a SQL Server database (as a BLOB).

PROBLEM: I'm trying access binary records that were created in Borland Delphi and stored in a SQL Server database (as a BLOB).

Q: What the heck is the syntax for accessing a two-D array in C#????

Here's an example:

const
  MAX_BOWLERS = 8;
  gMAX_FRAMES = 40;
  ...

type

TFrame = Record Balls : array[1..3] of ShortInt; // Pins standing: balls 1, 2 and 3 Pins : array[1..3] of ShortInt; CurrentBall : Byte; Score : Integer; // Current score (-1= undefined) Attributes : TFrameAttributes; ...

TFrames = Array[1..Max_Bowlers, 0..gMax_Frames] of TFrame;

TgameRec = Record Side : Byte; Bowlers : tBowlers; Frames : TFrames; ...

Soooooooo.开发者_如何学运维...

I've successfully got a valid "GameRec" over to C#-land.

I want to access GameRec.Frames[iBowler, iFrame].

Q: How do I define a C# type "TFrames = Array[1..Max_Bowlers, 0..gMax_Frames] of TFrame;" so that I can do it?

Thank you very much in advance .. PSM


I found a solution:

  1. Treat the 2-D array as its own struct, containing an array.

  2. The contained array is 1D, consisting of cols * rows elements

  3. Provide a C# "indexed property" so that external clients can access elements as though they were in a 2-D array (which, in terms of memory layout, they actually are!)

    // C# Definition for Delphi 2-D array
    [StructLayout(LayoutKind.Sequential, Pack = 4)]
    public unsafe struct TFrames
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst=(MAX_BOWLERS)*(gMAX_FRAMES+1))]
        private TFrame[] row;
        public TFrame this[int iBowler, int iFrame]
        {
            get
            {
                int ioffset = (iBowler * (gMAX_FRAMES+1)) + iFrame;
                return row[ioffset];
            }
        }
    }

   // C# client example
    public static string ConvertSplitToString(TgameRec currentGame, int iBowler)
    {
        StringBuilder sb = new StringBuilder();
        TFrames frames = currentGame.frames;
        for (int iFrame = 0; iFrame < 10; iFrame++)
        {
            if (frames[iBowler, iFrame].fSplit != 0)
                sb.Append('.');
            else 
                sb.Append(' ');
        }
        return sb.ToString ();
    }

0

精彩评论

暂无评论...
验证码 换一张
取 消