[C#]Ещё одна проблема с generics - как совместить generic и sizeof()
Но будет работать только, если T - value-type, очевидно.
upd. Но у тебя T - структура, так что все круто.
![](/images/graemlins/frown.gif)
Неужели не помогут генерики?
2. В чем генерики должны помочь?
Кстати говоря, то, что ты делаешь, можно сделать без unsafe кода, если использовать Marshal.PtrToStructure
upd. Если у тебя sizeof(T) будет четным и invert == true, ты перевернешь всю память, до какой дотянешься.
б) вижу, исправлю
public class MarshalHlp<T> where T : structВ этом случае вычисление размера будет происходить один раз, в момент компиляции конкретного типа MarshalHlp, и потери скорости не будет.
{
static int size = Marshal.SizeOf(typeof(T;
public static T Read(Stream stream, bool invert)
{
...
}
}
![](/images/graemlins/smile.gif)
Однако остаётся проблема с инвертированием. Меня не радует идея использования маршалинга в более-менее критичном по скорости коде. Как передать byte* вместо byte[], если это возможно?
Однако остаётся проблема с инвертированием. Меня не радует идея использования маршалинга в более-менее критичном по скорости коде.
Не осознал, где проблема. Поясни, пожалуйста.
Мне показалось, что при использовании Marshal.PtrToStructure лишний раз передаются данные и вдобавок маршалер должен разбираться, как их преобразовывать. Это накладно.
Я сейчас посмотрел, использование Marshal.PtrToStructure в два раза замедляет код. Если скорость критична, лучше действительно остаться в unsafe коде
void unsafe Invert(ref Chunk chunk)
{
fixed (Chunk * ptr = &chunk)
{
// cast to byte* and invert
}
}
Не станет ли существенно легче и быстрее?
чтоб потом хитрожопо преодолевать безопасный синтаксис чтоб добится скорости такой же как на тривиальном сишном коде?
![](/images/graemlins/grin.gif)
чтобы один раз написать хитрожопо, а потом писать КРАСИВО
А вот если сделать что-нить такое:
...
Не станет ли существенно легче и быстрее?
Читай тему с начала. Нужен generic метод
чорд! вся загвоздка в "Cannot take the address of, get the size of, or declare a pointer to a managed type ('T') "
Сделай как Красин говорит - запомни размер в константу.
Насколько я понял, у тебя проблема ещё и в дополнительном копировании памяти - когда ты проинверсенную структуру возвращаешь из метода. Вот я тебе и советую - сделай функцию Invert, которой передаётся ссылка на структуру, а она её inplace инвертит. Правда, я не уверен, что это возможно - как шарп работает с ref struct я не особенно понимаю =)
И буфер, в который считываешь фигню, тоже выдели статически.
И нефиг возвращать структуры, это медленно!
Поэтому я не вижу способов скопировать в неё данные напрямую из массива. Только маршалинг. А он слишком медленный, особенно для сложных структур
Используй макрогенератор и не парься.
тем-более что в C# вроде можно разбить описание класса на несколько файлов, так что гемора с этим будет немного.
Как поможет макрогенератор в случае, когда тип структуры я узнал в runtime-е?
Неверзелесс, можно и скомпилировать кусочек кода =)
Скомпилировать кусочек кода - это отличная потеря времени, а главное, нереальный гемор. Ведь в случае твоего решения, у нас не будет никакой поддержки от студии при использовании этого кода.
Для автора треда наиболее правильным решением будет пользоваться Marshal.PtrToStructure. В конце концов, этот метод и предназначен для решения такой задачи.
пусть автор трэда расскажет подробнее для чего это ему нужно.
почти наверняка решение существует значительно более простое.
Тваё, канешна, прогер неадекватный
![](/images/graemlins/wink.gif)
![](/images/graemlins/smile.gif)
Аргументы тогда приведи.
Насколько я понял, единственным выходом является именно использование Marshal, т.к. в C# нельзя указать, что тип должен быть именно неуправляемым. Более того неуправляемыми являются только предопределённые типы данных. Надеюсь в будущем такое ограничение будет снято
эээ, ты сериализацию переписываешь?
Кстати говоря, то, что ты делаешь, можно сделать без unsafe кода, если использовать Marshal.PtrToStructureНе понял, как без unsafe. Где взять IntPtr?
public static object GetStructure(byte [] array, int startIndex, Type type)
{
int length = Marshal.SizeOf(type);
IntPtr pointer = Marshal.AllocHGlobal(length);
Marshal.Copy(array, startIndex, pointer, length);
object result = Marshal.PtrToStructure(pointer, type);
Marshal.FreeHGlobal(pointer);
return result;
}
При этом возвращается забоксенная структура и при любых попытках что-нибудь с ней сделать будет происходить unboxing и прочее копирование.
Я с самого начала говорю - если хочется превратить массив байт в структуру, то нужно передавать ссылку на то место, куда нужно засовывать результат (например, массив структур, а возможно и ref будет работать).
Приведи полный код аналогичной функции у тебя, тогда можно будет сравнить по времени. А так - беспредметный спор.
Оставить комментарий
agaaaa
Error 6 Cannot take the address of, get the size of, or declare a pointer to a managed type ('T') D:\Coding\Projects\Lost\Lost\IO\StreamData.cs 33 49 Lost