Я провожу некоторые эксперименты, и мне нужно атомарно уменьшить 16-битное (короткое) значение в С#. Значение хранится в неуправляемой памяти, и не составляет труда убедиться, что значение выровнено по 16-битной границе виртуальной памяти.
Я обнаружил, что winnt.h (kernel32) предоставляет такую функцию: https://docs.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-interlockeddecrement16
Однако, когда я пытаюсь p/вызвать эту функцию из своего приложения .NET, я получаю следующую ошибку:
Unable to find an entry point named 'InterlockedDecrement16' in DLL 'kernel32.dll'.
Код импорта метода выглядит так:
[DllImport("kernel32.dll")]
public static extern int InterlockedDecrement16(ref short addend);
Почему я получаю эту ошибку, и видите ли вы другие альтернативы interlocked16 p/invoke, когда для этого нет встроенных компиляторов в C# (только 32-разрядные и 64-разрядные версии доступны на Заблокировано)
lock
вокруг своего атомарного значения. - person Liam   schedule 03.11.2020Interlocked.Decrement
a> это то, что вы должны использовать здесь. Int32 должен неявно преобразовываться в Int16, поэтому его можно использовать какshort
- person Liam   schedule 03.11.2020winnt.h
имеет такую функцию, раскрывая встроенную компилятор,kernel32
нет. Эта внутренняя сущность не раскрывается в управляемом мире; вы всегда можете обернуть его с помощью C++/CLR, если вам это действительно нужно - в противном случае просто сделать значение 32-битным - это путь наименьшего сопротивления, поскольку вы действительно не в состоянии продлить время выполнения. Существует действительно старая проблема, в которой упоминается об этом, но, похоже, никакой работы не было сделано. - person Jeroen Mostert   schedule 03.11.2020short
. Int32 содержит все значения для шорта и (как я уже сказал) существует неявное преобразование - person Liam   schedule 03.11.2020ref Int32
вref Int16
и наоборот. Подумайте немного о том, как может работать такая операция, и вы увидите, что невозможно реализовать атомарное обновление 16-битного значения, если все, что у вас есть, — это примитив, который атомарно обновляет 32-битное значение. Что бы C# ни предлагал в отделе неявного преобразования, это не имеет значения. Возможно, вы упускаете из виду, что это значение хранится в неуправляемой части памяти — мы не можем просто расширить значение. - person Jeroen Mostert   schedule 03.11.2020