Unity 6.3
0 онлайн 95 гостей 3 в системе
Вход
Программирование в Unity Шаг 107 из 210

Передача данных между управляемым и неуправляемым кодом

При передаче данных между управляемым и неуправляемым кодом необходимо учитывать, как данные хранятся и управляются в памяти. В этом разделе объясняется, как передавать данные между управляемым и неуправляемым кодом в Unity.

При передаче данных между функциями параметры и возвращаемые значения могут быть скопированы в стек или храниться в куче. Стек обычно используется для типов значений, и данные сохраняются в течение вызова функции. Данные с менее предсказуемым сроком жизни хранятся в куче. В C# время выполнения скрипта управляет кучей, что включает в себя перемещение данных и высвобождение памяти, которая больше не используется. В неуправляемом коде вы напрямую запрашиваете и управляете памятью кучи.

Когда вы вызываете неуправляемую функцию из управляемого кода или управляемую функцию из неуправляемого кода, обе стороны могут напрямую получить доступ к данным стека. Поэтому вы можете передавать небольшие типы значений, такие как float и int, без дополнительных мер предосторожности. Вам не нужно беспокоиться о том, что данные исчезнут до того, как другая сторона вызова получит к ним доступ.

Однако при передаче типов ссылок и более крупных типов значений, таких как строки, массивы и некоторые структуры, данные могут храниться в куче. В этом случае между управляемым и неуправляемым кодом передается только ссылка или указатель. Необходимо обеспечить, чтобы данные оставались в одном и том же месте памяти до тех пор, пока к ним можно получить доступ.

На протяжении обычного вызова в неуправляемый код, время выполнения сценария обрабатывает это за вас. В качестве части маршрутизации, оно сохраняет соответствующие управляемые данные живыми и на месте до возвращения вызова. Вам нужно только принять дополнительные меры для расширенных сценариев, когда неуправляемый код сохраняет ссылку на данные и доступ к ним после возвращения вызова, такие как асинхронный обратный вызов или указатель, который основной код хранит для последующего использования. В этих случаях вы можете использовать структуру GCHandle для "прикрепления" объекта в памяти. Время выполнения сценария не будет перемещать или освобождать прикрепленный объект, пока вы не удалите GCHandle.

 //Create a GCHandle to pin data in memory
 GCHandle handle = GCHandle.Alloc(yourObject, GCHandleType.Pinned);
 //... pass data to unmanaged code that retains it beyond the call ...
 handle.Free(); //Dispose of the handle when unmanaged code is finished

Примеры передачи различных типов данных см. в следующих разделах:

Тема Описание
Примитивные типы Как передавать примитивные типы значений, такие как int, float и char.
Структуры, классы и союзы Как передавать сложные типы.
NativeArrays Как передавать NativeArray объекты.
Струны Как передавать строковые объекты.