如何在 C# 中使用结构数组

How use Struct Array in C#

本文关键字:结构 数组      更新时间:2023-10-16

我是一个新的C#用户。我在下面有一个 C/C++ 结构:

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;

我使用 C# 定义相同的结构,如下所示:

[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;    
   }

但是,当我在 C# 项目中使用以下项目时:

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

编译器输出:

错误 CS0208:无法获取 的地址、获取大小或声明 指向托管类型 ('***.结果')

我的问题是为什么结构指针无法使用以及如何修复?

指针不能指向引用

或包含引用的结构,因为即使指针指向对象引用,也可以对对象引用进行垃圾回收。垃圾回收器不会跟踪对象是否由任何指针类型指向

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

本质上,因为 C# 是一种托管语言,所以它需要跟踪对对象的所有引用,以便知道何时对其进行 GC。如果在 OutResult 中声明指向诊断对象的指针,则 GC 将不知道新引用,并且稍后可以在使用对象时释放对象。

为了解决这个问题,我会亲自避开指针,除非你绝对必须使用它们。我不确定你的整个程序是什么,但如果你只是想传递引用,那么让OutResult成为引用类型(类)而不是值类型(结构)。C# 是一种托管语言,因此最好尝试并坚持使用托管上下文,特别是如果您还是初学者的话。

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