【问题标题】:How use Struct Array in C#如何在 C# 中使用结构数组
【发布时间】:2016-04-22 09:11:48
【问题描述】:

我是 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:无法获取地址、获取大小或声明 指向托管类型的指针 ('***.OutResult')

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

【问题讨论】:

  • 我在 C/C# 互操作方面没有任何经验。所以让我要求澄清一下:IIUC 类型 StringResultInfo 是通过程序的 C 部分中的 typedef 声明的。当您将其用作OutResult 中的类型时,C# 部分如何了解此名称?等效的 C# 类型似乎是 DF_TAdvOCRStringResultInfo
  • 是我的错,我忘了修改C#中的结构名;

标签: c# c++ c struct


【解决方案1】:

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

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

本质上因为 C# 是一种托管语言,它需要跟踪对对象的所有引用,以便知道何时对它进行 GC。如果你在 OutResult 中声明了一个指向 Diagnostics 对象的指针,那么 GC 就不会知道新的引用,并且稍后可能会在你使用它时处理掉你的对象。

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

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

【讨论】:

  • 非常感谢!最后,我用COM解决了这个问题!
猜你喜欢
  • 1970-01-01
  • 2018-02-22
  • 1970-01-01
  • 2018-09-21
  • 2015-12-18
  • 1970-01-01
  • 2011-01-22
  • 1970-01-01
相关资源
最近更新 更多