Указатели в C # Unity

8

Эй, я только недавно узнал об указателях, и мне интересно, как я могу использовать их в c # (я только что узнал о них в c ++) в единстве. У меня есть несколько вопросов.

  1. Указатели используют низкоуровневое программирование для поиска позиций различных значений на компьютере. Значит ли это, что вы можете просто получить доступ к значению переменной из любого скрипта?
  2. Если так, то как мне просто вызвать местоположение переменной с помощью только ее кода местоположения?
  3. Есть ли заметные различия между указателями в C # и C ++, которые я должен знать?
  4. Как я могу использовать указатели с типами переменных в Unity (Vector3s, Transforms, GameObjects и т.д ...)?

Есть еще много вопросов, которые я, вероятно, должен и хотел бы задать, так что если у вас есть дополнительная информация или источники.

Райан Генри
источник

Ответы:

6

В общем, для C # и, в частности, для Unity, я бы посоветовал против этого ... но, если вы действительно этого хотели или имели веские причины, вы могли бы.

В C # вам необходимо ознакомиться с тем, что называется небезопасным кодом . Испугался еще?

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

Таким образом, в основном C # был разработан с сборщиком мусора, как и многие языки сценариев. Общая идея состоит в том, чтобы попытаться абстрагировать понятие управления памятью, чтобы упростить разработку. Вы все равно можете получить утечку ресурсов, если не обнуляете свои объекты. Я, честно говоря, не большой сторонник GC и предпочел бы методы RAII , но это мир, в котором мы живем.

Однако большинство разработчиков на C ++ также согласны с тем, что в любом случае вы не должны использовать указатели напрямую, и им следует предпочесть использовать тип RAII, известный как умные указатели . Если вы находитесь на земле C, то вероятные указатели являются для вас второй натурой, но даже в этом случае они помогают в некоторой степени абстрагировать их.

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

Вы также можете использовать указатели в Unity, написав собственный плагин . Это опять-таки исключит сборку веб-плеера, но новая функция HTML5 работает на основе emscripten, поэтому, если вы планируете использовать это, вы, вероятно, могли бы, если вы будете осторожны. Собственные плагины позволяют расширять Unity для каждой платформы. Я написал собственный плагин для связи с некоторыми микроконтроллерами через последовательное соединение, например.

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

Изменить: Извините, если я кого-то обидел, потому что я знаю, что мои мысли о GC не являются популярным мнением в настоящее время.

Если вы действительно прочитаете мой ответ, вы заметите, что я не называю C # языком сценариев. Я сравниваю его со «многими языками сценариев», однако в контексте Unity он очень часто используется в качестве языка сценариев. Это что-то вроде DSL для Unity, если хотите. Часто вы увидите, что в этом контексте его даже называют сценарием Unity (это в основном относится к Javascript-альтернативе Unity для C #). Если вы добавите LLVM в свой конвейер, вы можете просто скомпилировать его в нативный код для платформы напрямую ... тогда как бы вы это назвали? Так что, на самом деле, я не хотел здесь раскалываться.

Многие замечательные ссылки на разработку программного обеспечения наполнены мнением:

Эффективный C ++ , Более эффективный C ++ , C ++ FAQ , Эффективный C # , Современный дизайн C ++ , Шаблоны проектирования ... И бесчисленное множество других. Я не чувствую, что это делает аргументы менее заслуживающими доверия, если они сопровождаются вдумчивым объяснением.

Я не совсем сказал: «Никогда не используйте указатели!» , На самом деле я до сих пор использую их голыми. Я сказал «в общем», как в «предпочитаю использовать безопасный код небезопасному коду в C #». Бывают ситуации, когда это может быть полезным, и это одна из действительно мощных возможностей C # для выбора инструментов. C # даже позволяет вам в некоторой степени иметь прозрачность в процессе GC, в отличие от таких языков, как Dart, и может очень легко привести к утечке ресурсов. Конечно, если вы являетесь единственным разработчиком небольшого проекта, это вряд ли проблема. Если вы работаете в команде, скажем, 10+ с сотнями тысяч строк кода, то это может быть сложно.

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

Мне нравится пример, приведенный Лассе, в котором производительность, возможно, продиктовала необходимость.

Мэтью Сандерс
источник
1
C # не является языком сценариев, хотя его можно использовать для этого. У Java тоже есть GC, и это не язык сценариев. Ответы с вашим собственным мнением, что лучше всего, не является объективным ответом, который мы ищем на этом сайте. Для особых целей что-то вроде небезопасного кода и указателей может быть действительно эффективным.
Лассе
1
Я не понимаю, почему этот ответ опровергнут - он очень информативен и показывает много исследований / знаний и ссылок для дальнейшего чтения. Особенно для @Lasse, что такое язык сценариев? Конечно, было бы точнее сказать «язык, который используется для написания сценариев в единстве», но я не вижу особых оснований для понижения голоса, потому что Мэтью пропустил 7 очевидных слов и использовал один (более) упрощенный термин.
Wondra
@wondra Я не голосовал, потому что ответ не дает понять, что есть места, где указатели могут очень хорошо использоваться в C #. Все зависит от цели и целевой платформы. На самом деле ответ пытается отпугнуть всех от использования указателей.
Лассе
1
@wondra Этот ответ едва ли отвечает на вопрос. Все, что он делает, это говорит не использовать указатели. Этот раздел комментариев не является подходящим местом для обсуждения этого. Вы можете присоединиться к чату, если считаете, что у вас есть больше аргументов.
Лассе
1
@Lasse не может убедить вас, и это не мой бой, но видя ваш ответ - вы написали точно так же, как этот ответ (который был опубликован раньше), более того, вы даже включили только подмножество (= меньше информации) по теме, как этот ответ.
Wondra
6

C # использует ссылки для передачи объектов, которые не являются типами значений . Это означает, что все обычно передается по ссылке. Если вы хотите передать тип значения по ссылке, вы можете использовать ключевое слово ref . Разница между ссылочным типом и типом значения заключается в том, что в зависимости от того, насколько велик тип значения, обычно требуется больше памяти, скопированной при передаче функции. Ссылка - это всего лишь 32 или 64 бита , или 4 байта, или 8 байтов. Вы можете повысить производительность своего кода в очень узких циклах, если будете использовать ссылки, а не просто копировать все данные, содержащиеся в типизированных переменных, предполагая, что они больше 4 или 8 байтов.

Например, в Unity любой объект MonoBehaviour (class) является ссылочным типом, а любой объект Vector3 (struct) является типом Value.

Также есть небезопасные блоки кода , которые позволят вам набирать код, который позволяет небезопасно создавать и изменять данные. Чтобы использовать небезопасный код, вы должны будете установить компилятор, чтобы разрешить небезопасный код. Указатели могут быть использованы таким образом. При использовании небезопасного кода не используются определенные проверки, которые существуют вместе с безопасным кодом, что затрудняет написание небезопасного кода без ошибок. Есть очень мало мест , которые могут извлечь выгоду из небезопасного кода на C #. На Unity небезопасный код поддерживается не на всех платформах. Обычно при работе с Unity достаточно использовать ссылки вместо небезопасных указателей.

Вот пример ( источник ) использования небезопасных указателей кода в C # с Unity:

public static class Rope
{
    // C# function declaration to match C++
    [DllImport(SlingshotImport.c_libName)]
    static unsafe extern void UpdateRopeParticlesUnsafe(
        Vector3* oldNew,
        Vector3* curr,
        int numParticles);

    // C# wrapper function for Unity C# script
    static void UpdateRopeParticles(
        Vector3[] oldNew,
        Vector3[] curr,
        int numParticles)
    {
        unsafe
        {
            fixed (Vector3* oldNewPtr = oldNew)
            fixed (Vector3* currPtr = curr)
            {
                UpdateRopeParticlesUnsafe(oldNewPtr, currPtr, numParticles);
            }
        }
    }
}
Лассе
источник
Мне интересно, что вы критикуете мой ответ и используете те же аргументы, за исключением другой релевантной информации, и включаете только краткое обсуждение значения против ссылочных типов. Вы могли бы, по крайней мере, упомянуть Boxing , JIT-оптимизации, которые иногда могли бы убрать накладные расходы при копировании типа значения, как избежать небезопасного с помощью маршалинга или, возможно, что небезопасный код не всегда быстрее, чем безопасный
Мэтью Сандерс
Извините, если вы чувствуете себя атакованным или обиженным. Это не было моим намерением. Я критиковал ваш ответ за то, что он показался мне основанным на мнениях, а не на фактах. Я дал ответы на заданные вопросы вместе с примером кода. По вашему ответу я не смог понять то, что объяснил в своем ответе, что, по моему мнению, было более уместным для задаваемого вопроса. Я не вижу, как GC имеет какое-либо отношение к "как я могу использовать указатели?" или я не видел, чтобы вы упоминали, как ссылки работают на C #, поскольку вопрос, казалось, предполагал, что переменные работают одинаково в C # и C ++.
Лассе
1
Не беспокойся. Спасибо за ваши извинения. Я упомянул GC, поскольку вам нужно знать, что передача указателей на управляемые типы может вызвать проблемы, если GC внезапно переместил объект. Я предположил, что читатель знает о системе типов C # и о том, как используются типы ссылок и значений.
Мэтью Сандерс
Ребята, вам действительно трудно принять ответ. Вы оба предоставили мне много информации, которая была необходима, поэтому я собираюсь проголосовать за вас обоих и приму ту, которая была первой. Я ничего не имею в виду. Мне просто трудно выбирать, и меня не пугает «небезопасный код». Я никогда не был тем, кто отступил от проблемы в любом случае. Хотя теперь я знаю, что работать с указателями нецелесообразно, так как это относится к многоплатформенной разработке. Я хочу поблагодарить вас всех за ваше время и мнения. и я сожалею, что начал Вторую Мировую Войну, не собирался этого делать.
Райан Генри