Выделение структуры c ++, содержащей указатели на другую структуру c ++ - PullRequest
2 голосов
/ 16 марта 2012

У меня проблема с правильным распределением структур 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 ]

1 голос
/ 16 марта 2012

Вы забыли объявить его как массив.Добавьте конструктор для их инициализации:

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

Не используйте никаких атрибутов, маршалинг по умолчанию хорош как есть.

0 голосов
/ 16 марта 2012

Не используйте UnmanagedType.LPStruct, см. этот пост .

EDIT Если у вас есть массив фиксированного размера, встроенный в структуру, вы должны следовать MSDN . Быстро вы должны объявить это поле как массив и указать, что это UnmanagedType.ByValArray. Вы также должны указать размер.

Если в структуре у вас есть только указатель на первый элемент массива, вам не нужно настраивать маршалинг, поведение по умолчанию правильное (как написано @Hans Passant)

...