编组包含指向另一个c ++结构的指针的c ++结构

时间:2012-03-16 10:10:01

标签: c# pointers marshalling

我有一个关于将c ++结构正确编组到c#中的问题。这些定义如下:

extern "C"
{
    //Geometry forms that could be used for envelope calculation
    enum GeometryForms  {RECTANGLE, TRIANGLE, ELLIPSE, CIRCLESECTOR};

    //Structure for coordinates 3D
    typedef struct Coordinates
    {
        double  longitude;      //longitude of the point in dezimal deg
        double  latitude;       //latitude of the point in dezimal deg
        double  altitude;       //heigth of the point in metres
    } Coordinates, *PCoordinates;


    //Envelope Data Struct
    typedef struct EnvelopeStruct
    {
        GeometryForms   GeometryAft;        // Geometry form of the aft section
        GeometryForms   GeometryBow;        // Geometry form of the bow section
        GeometryForms   GeometryCurve;      // Geometry form during direction change
        GeometryForms   Geometry3DAboveWL;  // Geometry form 3D under the water level
        GeometryForms   Geometry3DUnderWL;  // Geometry form 3D above the water level
        Coordinates     *PointsAft;         // Coordinates of the part of the envelope of the aft section
        Coordinates     *PointsBow;         // Coordinates of the part of the envelope of the bow section
        Coordinates     *PointsCurve;       // Coordinates of the envelope during direction change
        Coordinates     *Points3DAboveWL;   // Coordinates of the envelope above water level
        Coordinates     *Points3DUnderWL;   // Coordinates of the envelope under water level
    }EnvelopeStruct, *PEnvelopeStruct;


    //Structure includes all parameters that are used for the envelope calculation
    typedef struct CalculationParametersStruct
    {
        double  pos_long;           //Position of the vessel, longitude in decimal degree
        double  pos_lat;            //Position of the vessel, latitude in decimal degree
        double  pos_alt;            //Position of the vessel, altitude in metres
        double  pos_long_future;    //Predicted longitude of the vessel in decimal degree
        double  pos_lat_future;     //Predicted latitude of the vessel in decimal degree
        double  pos_alt_future;     //Predicted altitude of the vessel in metres
        float   pos_future_time;    //Time or timeinterval between actual position and predicted position
        double  sigma_long;         //Accuracy of actual longitude
        double  sigma_lat;          //Accuracy of actual latitude
        double  sigma_alt;          //Accuracy of actual altitude
        double  PL_long;            //Integrity value (protection level) into longitude
        double  PL_lat;             //Integrity value (protection level) into latitude
        double  length;             //length of the vessel in metres
        double  beam;               //beam of the vessel in metres
        double  draft;              //draft of the vessel in metres
        double  max_t;              //maximum trim
        double  v;                  //velocity of the vessel
        double  course;             //vessels heading
        double  rate;               //Rate of Turn of the vessel
        double  angle;              //Rudder Angle of the vessel
        double  coef;               //Maneuvering Coefficient
        double  scale;              //Dangerous Cargo Scale
        double  scale_lon;          
        double  scale_lat;
        double  wave_lon;
        double  wave_lat;
        double  ENC_reliability;            
    }CalculationParametersStruct, *PCalculationParametersStruct;

我尝试用c#中的后续代码完成,但它现在不起作用:

public enum GeometryForms { RECTANGLE, TRIANGLE, ELLIPSE, CIRCLESECTOR };

    [Serializable]
    [StructLayout(LayoutKind.Sequential)]
    public class Coordinates
    {
        public double longitude;        //longitude of the point in decimal deg
        public double latitude;     //latitude of the point in decimal deg
        public double altitude;     //height of the point in metres
    }

    [Serializable]
    [StructLayout(LayoutKind.Sequential)]
    public class EnvelopeStruct
    {
        public GeometryForms GeometryAft;       // Geometry form of the aft section
        public GeometryForms GeometryBow;       // Geometry form of the bow section
        public GeometryForms GeometryCurve;     // Geometry form during direction change
        public GeometryForms Geometry3DAboveWL; // Geometry form 3D under the water level
        public GeometryForms Geometry3DUnderWL; // Geometry form 3D above the water level
        [MarshalAs(UnmanagedType.LPStruct, SizeConst = 96)]
        public Coordinates PointsAft;           // Coordinates of the part of the envelope of the aft section
        [MarshalAs(UnmanagedType.LPStruct, SizeConst = 96)]
        public Coordinates PointsBow;           // Coordinates of the part of the envelope of the bow section
        [MarshalAs(UnmanagedType.LPStruct, SizeConst = 4320)]
        public Coordinates PointsCurve;     // Coordinates of the envelope during direction change
        [MarshalAs(UnmanagedType.LPStruct, SizeConst = 96)]
        public Coordinates Points3DAboveWL; // Coordinates of the envelope above water level
        [MarshalAs(UnmanagedType.LPStruct, SizeConst = 96)]
        public Coordinates Points3DUnderWL; // Coordinates of the envelope under water level
    }

    [Serializable]
    [StructLayout(LayoutKind.Sequential)]
    public class CalculationParametersStruct
    {
        public double pos_long;         //Position of the vessel, longitude in decimal degree
        public double pos_lat;          //Position of the vessel, latitude in decimal degree
        public double pos_alt;          //Position of the vessel, altitude in metres
        public double pos_long_future;  //Predicted longitude of the vessel in decimal degree
        public double pos_lat_future;       //Predicted latitude of the vessel in decimal degree
        public double pos_alt_future;       //Predicted altitude of the vessel in metres
        public float pos_future_time;   //Time or timeinterval between actual position and predicted position
        public double sigma_long;           //Accuracy of actual longitude
        public double sigma_lat;            //Accuracy of actual latitude
        public double sigma_alt;            //Accuracy of actual altitude
        public double PL_long;          //Integrity value (protection level) into longitude
        public double PL_lat;               //Integrity value (protection level) into latitude
        public double length;               //length of the vessel in metres
        public double beam;             //beam of the vessel in metres
        public double draft;                //draft of the vessel in metres
        public double max_t;                //maximum trim
        public double v;                    //velocity of the vessel
        public double course;               //vessels heading
        public double rate;             //Rate of Turn of the vessel
        public double angle;                //Rudder Angle of the vessel
        public double coef;             //Maneuvering Coefficient
        public double scale;                //Dangerous Cargo Scale
        public double scale_lon;
        public double scale_lat;
        public double wave_lon;
        public double wave_lat;
        public double ENC_reliability;
    }

我收到错误CS0021:当我尝试访问

时,无法将带有[]的索引应用于“EnvelopeCalculatorWrapper.Coordinates”类型的表达式
[MarshalAs(UnmanagedType.LPStruct, SizeConst = 96)]
            public Coordinates PointsAft;

作为c#中的数组,方式为:

calc.envelope.PointsAft[i].longitude

有人知道怎么做!

提前致谢!

干杯,斯蒂芬

2 个答案:

答案 0 :(得分:1)

您忘了将其声明为数组。添加构造函数来初始化它们:

    [StructLayout(LayoutKind.Sequential)]
    public class EnvelopeStruct {
        public EnvelopeStruct() {
            this.PointsAft = new Coordinates[4];
            // etc..
        }
        public Coordinates[] PointsAft;
        // etc..
    }

不要使用任何属性,默认编组是好的。

答案 1 :(得分:0)

请勿使用UnmanagedType.LPStruct,请参阅this post

修改 如果您在结构中嵌入了固定大小的数组,则应遵循MSDN。很快你应该将该字段声明为数组并指定它是UnmanagedType.ByValArray。你也必须指定大小。

如果在结构中,你只有一个指向数组第一个元素的指针,你不需要任何自定义封送,默认行为是正确的(由@Hans Passant发布)