Я хочу преобразовать массив ushort в короткий массив без выделения новой памяти в ядре C #.
Также преобразуйте любой тип, например, byte [], в short [] или наоборот - для преобразования необходимо сохранить одинаковый размер в памяти как для источника, так и для пункта назначения
В C был синтаксис "union", к которому тип можно ссылаться с помощью приведения типов - я не нашел никакого эквивалента для C # (который работает только для не примитивных типов).
Один из способов - написать код
ushort[] res = new ushort[1024 * 1024 * 1024];
short[] s = new short[1024 * 1024 * 1024];
Buffer.BlockCopy(s, 0, res, 0, s.Length * 2);
... но я не хочу выделять значение 's' - это слишком много памяти и может привести к утечке памяти.
Другая альтернатива, которую я использую, - это небезопасный режим.
код:
unsafe
{
ushort[] res = new ushort[10241024]; // large allocating
fixed (ushort* ss = &res[0])
{
IntPtr ps = (IntPtr)ss;
short[] s0 = (short[])Marshal.PtrToStructure(ps, typeof(short[]));
}
}
столкнуться с исключением.
Для этого объекта не определен конструктор без параметров. *1024*
...
в System.RuntimeTypeHandle.CreateInstance (тип RuntimeType, логическое значение publicOnly, логическое исключение wrapException, логическое значение & canBeCached, RuntimeMethodHandleInternal & ctor)
at System.RuntimeType.CreateInstanceSlow (логическое значение publicOnly, логическое значение wrapExceptions, логическое значение skipCheckThis, логическое значение fillCache)
в System.Runtime.InteropServices.Marshal.PtrToStructure (IntPtr ptr, Тип структурыType)
Как я могу в конечном итоге преобразовать этот большой массив в 1 Гбайт без необходимости выделять новую память?
Можно ли преобразовать тип массива из неуправляемого типа в управляемый тип?
Я предпочитаю использовать небезопасный режим, если это возможно.
После глубокого поиска я нашел решение, в котором я бы участвовал (и редактировал этот пост), но у него есть проблема, описанная ниже:
Это код работает очень хорошо, если массивы имеют одинаковый размер - Есть новый вопрос - Как я могу решить это для не того же размера базового типа массива (то есть short [] vs byte [])?
Единственное, что я не могу преобразовать из короткого [] в байт [].
(Спасибо, какой-то блог в интернете:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/06ac44b0-30d8-44a1-86a4-1716dc431c62/how-to-convert-an-intptr-to-an-object-in-c?forum=clr)
Это работает на ядре C #, а также на C # .NET
Во-первых, создайте класс:
public static class MyConverter
{
public static unsafe T GetInstance<T>(IntPtr pointer)
{
try
{
var fakeInstance = default(T);
TypedReference typedReference = __makeref(fakeInstance);
*(IntPtr*)(&typedReference) = pointer;
T instance = (T) __refvalue(typedReference,T);
return instance;
}
catch
{
return default(T);
}
}
}
и может использовать его в таком коде:
ushort[] x = new ushort[1024];
GCHandle handle1 = GCHandle.Alloc(x);
IntPtr px = (IntPtr)handle1;
x[0] = 1;
x[1] = 2;
x[2] = 3;
short[] s = MyConverter.GetInstance<short[]>(px);
Это решение преобразует ushort [] в short [] без потери памяти.
Спасибо.