2016-04-22 67 views
2

我是一个新的C#用户。我有一个C/C++结构如下:如何在C#中使用Struct数组#

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 

Complier输出:

错误CS0208:无法取地址,得到的大小,或者声明 一个指向托管类型(“***。OutResult”)

我的问题是,为什么结构指针不能使用,如何固定?

+0

我在C/C#互操作中没有任何经验。因此,让我澄清一下:IIUC'StringResultInfo'类型是通过程序的C部分中的'typedef'声明的。当你在'OutResult'中使用它作为类型时,C#部分如何了解这个名称?等价的C#类型看起来是'DF_TAdvOCRStringResultInfo'。 –

+0

这是我的错,我忘了修改C#中的结构名称; – halolzx

回答

2

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

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;  
} 
+0

非常感谢!最后,我用COM来解决这个问题! – halolzx