Пожалуйста, взгляните на следующий код 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
не сохраняет за пределами фиксированного блока. Это так?? Или это связано с какой-то другой проблемой?
Это не действительный код, сборщик мусора может только обновить значение vrt_ptr
а также tris_ptr
переменные. Но неуправляемый код использует копия из этих указателей значение копии не может быть обновлено GC. Так что, если происходит сборка мусора в то время как выполняется неуправляемый код, например, когда другие потоки в программе запускают коллекцию, тогда неуправляемый код будет считывать данные мусора через копию указателя. Очень трудно диагностировать, это случается не очень часто.
Вы должен закрепить вершины и трис-массивы. В вашем случае это уже умело сделал маршаллер pinvoke, просто передавая массивы напрямую, без использования фиксированный. Fix:
double* ptr = compute(vertices, 5, tris, 5);
Скорректируйте объявление pinvoke соответствующим образом, заменив double * на double [].
Теперь вам также придется иметь дело с вероятной причиной, по которой вы написали этот код. Есть нет Сценарий, в котором приведение int [] к double [] всегда допустимо, вероятная причина, по которой вы получили результат мусора раньше, чем может случиться катастрофа GC. Если вы не можете обновить объявление трис по какой-то причине вы должны создать двойной [] перед вызовом.
Других решений пока нет …