简体   繁体   中英

How use Struct Array in C#

I am a new C# user. I have a C/C++ struct below:

typedef struct
{
    float x;
    float y;
}Point2f;

typedef struct
{
    int id;
    unsigned char charcode;
}CharResultInfo;

typedef struct
{
   int  strlength;
   unsigned char strval[1024];
   CharResultInfo charinfo[1024];
}StringResultInfo;

typedef struct
{
  int threshold;
  int polarity;                         
  bool inverted;
}Diagnotices;

typedef struct 
{
    Point2f  regioncenter;                           
    StringResultInfo stringinfo;
    Diagnotics diagnotics;                  
}SingleOutResult;

I use C# to define the same struct like below:

[StructLayoutAttribute(LayoutKind.Sequential)]
public struct  Point2f    
{
    public double x;
    public double y;
}

[StructLayoutAttribute(LayoutKind.Sequential)]
public unsafe struct DF_TAdvOCRCharResultInfo
{
   public Int32 id;
   public char charcode;
}

[StructLayoutAttribute(LayoutKind.Sequential)]
public unsafe struct DF_TAdvOCRStringResultInfo
{
   public int strlength;
   [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 1024)]
   public string strval;   
   [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 1024, ArraySubType = UnmanagedType.Struct)]
   public CharResultInfo[]  charinfo;
}


[StructLayoutAttribute(LayoutKind.Sequential)]
public unsafe struct Diagnotics
{
   public Int32  polarity; 
   [MarshalAsAttribute(UnmanagedType.I1)]
   public bool   inverted;  
}

 [StructLayoutAttribute(LayoutKind.Sequential)]
   public unsafe struct OutResult
   {
       public Point2f regioncenter; 
       public StringResultInfo stringinfo;
       public Diagnotics  diagnotics;    
   }

However, When I used below in C# project:

OutResult *pResult = (OutResult *)inputparam;  //inputparam input from C/C++ dll

the Complier output:

error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('***.OutResult')

My Question is why Struct Pointer cannot used and how to fixed?

A pointer cannot point to a reference or to a struct that contains references, because an object reference can be garbage collected even if a pointer is pointing to it. The garbage collector does not keep track of whether an object is being pointed to by any pointer types.

https://msdn.microsoft.com/en-us/library/y31yhkeb.aspx

Essentially because C# is a managed language it needs to track all the references to the object in order to know when to GC it. If you declare a pointer to the Diagnostics object in your OutResult then the GC wouldn't be aware of the new reference and could later dispose of your object whilst you are using it.

To fix that I would personally steer clear of pointers unless you absolutely must use them. I'm not sure what your overall program is but if you simply want to pass around references then make OutResult a reference type (class) rather than a value type (struct). C# is a managed language and so it's always best to try and stick to a managed context, particulally if you're still a beginner as you say.

public class OutResult
{
    public Point2f regioncenter; 
    public StringResultInfo stringinfo;
    public Diagnotics  diagnotics;    
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM