Сохраняются ли изменения в указателе внутри фиксированного блока или нет?

Пожалуйста, взгляните на следующий код C #:

    double* ptr;

fixed(double* vrt_ptr = &vertices[0])
{
fixed(int* tris_ptr = &tris[0])
{
ptr = compute(vrt_ptr, 5, (double*)tris_ptr, 5);
// compute() is a native C++ function
}
}

Debug.Log("Vertices Recieved: " + *ptr);
/* and so on */

У меня есть значение мусора от * ptr. У меня есть подозрение, что массив назначен ptr от compute не сохраняет за пределами фиксированного блока. Это так?? Или это связано с какой-то другой проблемой?

2

Решение

Это не действительный код, сборщик мусора может только обновить значение vrt_ptr а также tris_ptr переменные. Но неуправляемый код использует копия из этих указателей значение копии не может быть обновлено GC. Так что, если происходит сборка мусора в то время как выполняется неуправляемый код, например, когда другие потоки в программе запускают коллекцию, тогда неуправляемый код будет считывать данные мусора через копию указателя. Очень трудно диагностировать, это случается не очень часто.

Вы должен закрепить вершины и трис-массивы. В вашем случае это уже умело сделал маршаллер pinvoke, просто передавая массивы напрямую, без использования фиксированный. Fix:

   double* ptr = compute(vertices, 5, tris, 5);

Скорректируйте объявление pinvoke соответствующим образом, заменив double * на double [].

Теперь вам также придется иметь дело с вероятной причиной, по которой вы написали этот код. Есть нет Сценарий, в котором приведение int [] к double [] всегда допустимо, вероятная причина, по которой вы получили результат мусора раньше, чем может случиться катастрофа GC. Если вы не можете обновить объявление трис по какой-то причине вы должны создать двойной [] перед вызовом.

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]