Изключение за нарушение на достъпа при използване на метода Marshal.PtrToStructure в цикъл

В моята програма (C#) използвах метода Marshal.PtrToStructure за преобразуване на обект, добавяне на адрес на памет към структура в цикъл. При първия елемент това работи нормално. Но при втория елемент възниква изключение за нарушение на достъпа.

Изключението за нарушаване на достъпа възниква само при win 7 (64 бита), не се случва при win xp (32 бита).

Не знам причина и решение за това.

Моля, помогни ми.

Забележка: Използвам .NET Framework 3.5.

Код по-долу:

[StructLayout(LayoutKind.Sequential)]
public struct gpc_vertex
{
    public float x;
    public float y;
};

private ArrayList DoPolygonOperation()
{
    IntPtr currentVertex = vertexList.vertexes;

    gpc_vertex oVertext = new gpc_vertex();

    for (int j = 0; j < vertexList.num_vertices; j++)
    {
        PositionF pos = new PositionF();
        oVertext = (gpc_vertex)Marshal.PtrToStructure(currentVertex, typeof(gpc_vertex));
        //Access violation exception
        pos.X = oVertext.x;
        pos.Y = oVertext.y;
        Marshal.DestroyStructure(currentVertex, typeof(gpc_vertex));
        currentVertex = (IntPtr)((int)currentVertex.ToInt64() + Marshal.SizeOf(oVertext));

        posList.Add(pos);
    }
}

Благодаря.


person Nguyen Thanh    schedule 05.06.2013    source източник
comment
DestroyStructure не изглежда необходимо тук, но не изглежда и вредно.   -  person Medinoc    schedule 05.06.2013
comment
Няма начин да разберете от кода дали currentVertex е валиден указател, който действително сочи към неуправляван масив от върхове с елементи num_vertices. Процесорът ви казва, когато не е валиден, като повдига AccessViolationException. Прехвърлянето на IntPtr към int също е много добър начин да прецакате показалеца.   -  person Hans Passant    schedule 06.06.2013


Отговори (1)


Когато променя някакъв код, нарушение на достъпа не възниква. Въпреки това не разбирам основната причина за този проблем. Какво изключение за нарушение на достъпа възниква?

Модифициране на кода по-долу:

private ArrayList DoPolygonOperation()
{
  IntPtr currentVertex = vertexList.vertexes;

  gpc_vertex oVertext = new gpc_vertex();
  int currentOffset = 0; 
  for (int j = 0; j < vertexList.num_vertices; j++)
  {
    PositionF pos = new PositionF();
    oVertext = (gpc_vertex)Marshal.PtrToStructure((IntPtr)(currentVertex.ToInt64() + currentOffset), typeof(gpc_vertex));
    pos.X = oVertext.x;
    pos.Y = oVertext.y;
    Marshal.DestroyStructure(currentVertex, typeof(gpc_vertex));
    currentOffset += Marshal.SizeOf(oVertext);

    posList.Add(pos);
 }
}
person Nguyen Thanh    schedule 06.06.2013