Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: C++/CLI Как использовать BinarySearch?  (Прочитано 7054 раз)
0 Пользователей и 1 Гость смотрят эту тему.
jur
Помогающий

lt
Offline Offline

« : 23-05-2014 18:53 » 

Привет!

Настала пора применить .NET. Не сам, жизнь заставила...

Прочитав много всего я было подумал, что вся эта бодяга с .NET придумана для облегчения жизни программиста. Однако, в последнее время я стал в этом утверждении серьезно сомневаться... Расскажу историю. Пару дней назад мне в голову пришла идея использовать в своей программе (утилита для прошивки фирмваре в микроконтроллер) бинарные ресурсы. Типа, положу-ка я бинарный файл моей прошивки в ресурсы программы и потом спокойно возьму его оттуда, заменю в нем сериальный номер прибора (строка ASCII символов) и спокойно запрограммирую измененный двоичный файл в микроконтроллер.

Счаз!

Начать с того, что простое считывание двоичных данных из ресурсов программы - "неподъемная для миллионов" задача! :-) Честно, искал в Интернете, натыкался на миллионы таких вопросов, на большинство из которых давались совершенно идиотские ответы... Так ничего и не нашел (я ведь не могу посвятить ответу на этот вопрос остаток жизни!). Выручила книга уважаемого Stephen R. G. Fraser с замечательным названием "Pro Visual C++/CLI and the .NET 3.5 Platform". (Однако, пока прочитал еще только процентов 5 этой замечательной книги.) Оказывается в жизни еще присутствуют другие краски, кроме бесконечного числа оттенков черного! :-) Вопрос с ресурсами был решен просто и легко, чего я, собственно, и ожидал.

Воодушевленный первым успехом, я подумал, что .NET не является инструментом исключительно для программеров "поколения ДОТ-нет"! Значит и я смогу применять его и дальше! Но - споткнулся...

Вы не поверите, но простейшая вещь - поиск начала последовательности байт в бинарном массиве - подкосила, таки, мой радужный оптимизм... Я говорю о методе "BinarySearch" в двоичном массиве. Конечно, я на-раз напишу такую мелочь сам (на любом используемом мной языке). Но ведь я еще не лишился воодушевления! Хочу понять наконец ту самую "Большую Программистскую Тайну" этого самого .NET!

Мой код крайне прост:

array<Byte>^ bytes;

В "bytes" я получаю двоичный массив с прошивкой. Теперь мне нужно заменить 12 байт шаблона серийного номера на реальный номер, введенный настройщиком платы. Строка

Byte index = Array::BinarySearch(bytes, s);  // В "s" лежит серийный номер в виде "123ABC123456"

компилируется нормально, но при выполнении дает ошибку: "Failed to compare two elements in the array."

Неужели и тут окажется, что для того, чтобы сделать проще, придется все делать гораздо сложнее, чем "без всех этих забот"?!

Делать поиск бинарной подстроки самому? (Это, понятно, как два пальца...) Или как?
Записан

MPEG-4 - в массы!
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 23-05-2014 19:44 » 

jur, ну во-первых, тип byte и тип char - это очень разные типы. Хотя бы потому, что byte - это unsigned int8, а char - unsigned int16. И в отличие от C, никакой "автоматической конвертации" в .NET нет. И это правильно: меньше поводов сделать косяк. Не задумываясь о том, что ты делаешь, ты бы вот тут и ошибся. Потому что битовое представление строки в старшем байте каждого символа имеет 0, и гипотетический binary search попросту не нашёл бы такой последовательности. Как говорится, надо "учить матчасть". Во-вторых, нужно читать документацию, прежде чем делать вызовы тех или иных стандартных методов. Ибо ясно сказано
Цитата
Searches an entire one-dimensional sorted Array for a specific element, using the IComparable interface implemented by each element of the Array and by the specified object.
что:
1) второй аргумент как объект сравнивается с каждым элементом массива - т.е. вся строка сравнивается с каждым байтом массива;
2) элементы массива должны реализовывать интерфейс IComparable, чего тип byte, разумеется, не делает;

Ну и в-третьих самое главное (!): binary search - это поиск в отсортированном массиве по битам методом деления пополам. Т.е. если ты свой ресурс (прошивку) отсортируешь с целью что-то найти, тебе эти байты больше уже не понадобятся.

Откуда следует нехитрый вывод, что ты вообще полную хрень написал, которая не заработает никогда и ни при каких условиях, потому что бессмысленна, а ты вообще не понимаешь, что делаешь - подразумевая совсем не то, чем что-то является на самом деле.

Первейшим делом тебе надо строчку сконвертировать в массив байтов. Чтобы сравнивать подобное с подобным. Способов это сделать масса, и самый правильный использовать класс System.Text.ASCIIEncoding, который как раз строчку и превращает в последовательность байтов в нужной (ASCII) кодировке. А затем уже искать подмассив в массиве.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
jur
Помогающий

lt
Offline Offline

« Ответ #2 : 23-05-2014 20:09 » 

jur, ну во-первых, тип byte и тип char - это очень разные типы. Хотя бы потому, что byte - это unsigned int8, а char - unsigned int16.

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

1) второй аргумент как объект сравнивается с каждым элементом массива - т.е. вся строка сравнивается с каждым байтом массива;

Вот это-то меня и смутило! Что за хрень?! Я-то думал, что эта функция делает что-то вроде strstr, т.е. ищет подстроку в строке. Только речь идет о двух двоичных последовательностях. А тут на тебе...

Ну и в-третьих самое главное (!): binary search - это поиск в отсортированном массиве по битам методом деления пополам. Т.е. если ты свой ресурс (прошивку) отсортируешь с целью что-то найти, тебе эти байты больше уже не понадобятся.

Тем более чушь какая-то... Ведь это BinarySearch, т.е. поиск одних бинарных данных в других. При чем тут сортировка?... Не, я понимаю, это такое требование. Но оно отнюдь не очевидно и мою задачу не решает.

Откуда следует нехитрый вывод, что ты вообще полную хрень написал, которая не заработает никогда и ни при каких условиях, потому что бессмысленна, а ты вообще не понимаешь, что делаешь - подразумевая совсем не то, чем что-то является на самом деле.

:-) Не менее нехитрый вывод тот, что я написал сообщение в разделе "Начинающим", что подразумевает, что я не знаю, как реализовать то, что мне нужно. Что именно мне нужно - я расписал подробно и красочно :-) Нет?!

Резюме. Да, я в этом самом C++/CLI новичок. Да, я пока не умею очень многих вещей. Так помоги! Если знаешь как. Свою задачу я расписал предельно понятно: найти двоичный подмассив в другом двоичном массиве. (Конечно, я их оба приведу к виду array<Byte>.)

Поможешь?

P.S. Я попробовал так:

     array<Byte>^ s = { '1','2','3' };
     Byte index = Array::BinarySearch(bytes, s);

та же ошибка: "Failed to compare two elements in the array". Хотя теперь оба массива одинаковы.
« Последнее редактирование: 23-05-2014 20:27 от jur » Записан

MPEG-4 - в массы!
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 23-05-2014 20:52 » 

Цитата: jur
Вот это-то меня и смутило! Что за хрень?! Я-то думал, что эта функция делает что-то вроде strstr, т.е. ищет подстроку в строке. Только речь идет о двух двоичных последовательностях. А тут на тебе...
Скорее это относится к пожеланию, чтобы функция работала как strstr - вот это точно хрень. Есть атомарные объекты и есть коллекции. Аргументами функции являются коллекция (массив) и объект. С какой стати функция должна предполагать, что первый аргумент - это на самом деле битовый атомарный объект? Тогда и аргументы были бы object и object, и сам метод не к классу Array относился бы.

Цитата: jur
Ведь это BinarySearch, т.е. поиск одних бинарных данных в других. При чем тут сортировка?...
При том, что "двоичный поиск" (алгоритмом деления пополам) и "битовый/бинарный поиск" (сравнение последовательностей битов, хотя тоже делением пополам) - это разные вещи. В данном случае BinarySearch означает именно первое, а совсем не второе.

Цитата: jur
Да, я в этом самом C++/CLI новичок. Да, я пока не умею очень многих вещей. Так помоги!
Я и помогаю. Т.е. ты берёшь и полностью язык C тащишь в .NET, ожидая, что .NET Framework - это что-то типа STL. Вот это хрень, от которой надо избавляться. Тогда и последствий вроде вышеописанного не будет. Твоя ошибка в том, что .NET ты не знаешь, но обращаешься с ним так, будто знаешь. Как только перестанешь махать шашкой и начнёшь читать MSDN перед тем, как чем-то воспользоваться, так и прогресс появится.

Цитата: jur
Я попробовал так
Я не вижу в том, что ты попробовал, алгоритма поиска подмассива в массиве. Хотя выше красочно было расписано, что BinarySearch
Цитата: Dimka
не заработает никогда и ни при каких условиях
Кое-кому нравится ходить по граблям.

Алгоритм поиска подмассива в доску простой и описан в классической литературе типа книжки Вирта.
Цитата: jur
Конечно, я на-раз напишу такую мелочь сам
Ну и где написанное?
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
jur
Помогающий

lt
Offline Offline

« Ответ #4 : 24-05-2014 08:24 » 

Скорее это относится к пожеланию, чтобы функция работала как strstr - вот это точно хрень.

С чего ты это взял?! Я же ясно написал: "Я-то думал, что эта функция делает что-то вроде strstr, т.е. ищет подстроку в строке". Где это ты увидел пожелание? :-)

Я и помогаю. Т.е. ты берёшь и полностью язык C тащишь в .NET, ожидая, что .NET Framework - это что-то типа STL. Вот это хрень, от которой надо избавляться. Тогда и последствий вроде вышеописанного не будет. Твоя ошибка в том, что .NET ты не знаешь, но обращаешься с ним так, будто знаешь. Как только перестанешь махать шашкой и начнёшь читать MSDN перед тем, как чем-то воспользоваться, так и прогресс появится.

Это так нынче помощь называется?... ".NET ты не знаешь, но обращаешься с ним так, будто знаешь" - вообще апофеоз... То, что мое сообщение в разделе "Начинающим" до тебя не доходит? Ты сделал странный вывод, что я считаю, что знаю .NET! :-)

Вместо пустых слов сказал бы лучше, как сделать поиск двоичного подмассива в двоичном массиве. Я тебя удивлю, но в MSDN ответа на этот простой вопрос я не нашел. (Понимаю, плохо искал. Но когда информации слишком много, искать в ней что-то нисколько не легче, чем когда ее мало...)

Алгоритм поиска подмассива в доску простой и описан в классической литературе типа книжки Вирта.

Тогда подскажи, пожалуйста, в какой именно книжке Вирта описано решение моей задачи средствами C++/CLI?

Да, согласен, я забыл указать, что разрабатываю свою программу в Микрософтовской Визуальной Студии, проект Visual C++ / CLR.

Ну и где написанное?

Смеешься? Я же ясно сказал, что хочу решить эту простую задачу средствами .NET. Просто на C/C++ я эту задачу решу лёгко. Ведь не заявишь же ты, что средствами .NET поиск двоичного подмассива в двоичном массиве решить невозможно? Или заявишь?... :-)

Итак, подскажешь, где про это почитать? (Только, прошу, не говори "читать MSDN", скажи по-конкретнее.)

Записан

MPEG-4 - в массы!
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 24-05-2014 10:05 » 

Цитата: jur
Я-то думал
Чтобы что-то думать, нужно иметь основания. Вот я и говорю, что оснований нет, а ты полагаешь, что они есть. В данном случае надо не думать, а читать спецификации.

Цитата: jur
Ты сделал странный вывод, что я считаю, что знаю .NET!
И поэтому "думал" и преполагал нечто о функциях которые не знаешь. Это не странный вывод, это констатация порочной практики.

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

Цитата: jur
Я же ясно сказал, что хочу решить эту простую задачу средствами .NET.
Студия перед тобой, язык понятный - пиши алгоритм. В чём проблема?
Цитата: jur
я на-раз напишу такую мелочь сам (на любом используемом мной языке)
Вперёд! Назвался груздем - полезай в кузов.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
jur
Помогающий

lt
Offline Offline

« Ответ #6 : 24-05-2014 13:06 » 

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

Кому-то поиск двоичного подмассива в двоичном массиве может показаться функцией бессмысленной, а кому-то - нет. Кому-то и поиск подстроки может показаться ненужным. Но вот, например, мне поиск двоичного подмассива как раз бессмысленным не кажется, потому что он мне понадобился :-)

Ладно, это философия и дело вкуса.

Цитата: jur
Я же ясно сказал, что хочу решить эту простую задачу средствами .NET.
Студия перед тобой, язык понятный - пиши алгоритм. В чём проблема?

Проблема в том, что я не знаю .NET и поэтому хочу начать в ней разбираться :-) Возникла передо мной задача - вот я и пытаюсь решить ее средствами C++/CLI. Например, при вводе настройщиком сериального номера в соответствующий TextBox, производится реакция на событие TextChanged. В функции проверки введенного текста я использую методы Char::IsDigit и Char::IsLetter (сериальный номер состоит только из них). Следуя твоей логике мне не следовало искать и понимать эти два метода, а написать их самому, так? Зачем тогда эта .NET нужна?!

Точно так же я попытался найти возможность поиска двоичного подмассива в другом двоичном массиве. А же не знаю, есть такая возможность или нет! Так я ведь заранее не знал, что существуют методы IsDigit и IsLetter, пока их не нашел и не понял, как их использовать.

Цитата: jur
я на-раз напишу такую мелочь сам (на любом используемом мной языке)
Вперёд! Назвался груздем - полезай в кузов.

Да запросто. Вот минимальный вариант:

Код:
BYTE* firmware_array;
int   firmware_array_len;
BYTE* serial_number_array;
int   serial_number_array_len;

// Тут инициализация указателей, установка переменных, проверка их правильности

BYTE* serial_number_array_place = NULL;

for(int i = 0;i < (firmware_array_len - serial_number_array_len);i++)
{
  if(memcmp(firmware_array + i, serial_number_array, serial_number_array_len) == 0)
  {
    serial_number_array_place = firmware_array + i;
    break;
  }
}

if( !serial_number_array_place )
{
  // Вывести сообщение: "Не нашел места SN'а, мать его..."
}
else
{
  // поместить введенный SN в фирмваре и прошить микроконтроллер
}

Но только этот код не будет managed, все восторги по поводу кульности .NET пройдут мимо меня :-)

Вот я и говорю, задача сугубо практическая, житейская, и я наивно подумал, что в этой ее части я смогу получить помощь от технологии .NET. То, что я ее получить не могу - не знал, ибо ничуть не являюсь телепатом :-)

P.S. У меня еще миллион похожих "ненужных" вопросов, но я пока не буду так, сходу нагружать форумчан :-)


« Последнее редактирование: 24-05-2014 13:08 от jur » Записан

MPEG-4 - в массы!
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 24-05-2014 13:28 » 

Цитата: jur
Например, при вводе настройщиком сериального номера в соответствующий TextBox, производится реакция на событие TextChanged. В функции проверки введенного текста я использую методы Char::IsDigit и Char::IsLetter (сериальный номер состоит только из них). Следуя твоей логике мне не следовало искать и понимать эти два метода, а написать их самому, так? Зачем тогда эта .NET нужна?!
Ну вообще-то гораздо удобнее использовать регулярные выражения для поиска в строке нужного или не нужного. Удобнее в том смысле, что нет необходимости обрабатывать строки как цепочки символов. Даже более того, обычно в .NET так не делают. К тому же строка в .NET - это не область памяти с произвольными операциями внутри неё, а константа. Любая операция над строкой приводит к копированию исходной и созданию новой модифицированной строки. Именно поэтому практики из языка C в данном случае порочны.

Цитата: jur
Но только этот код не будет managed, все восторги по поводу кульности .NET пройдут мимо меня Улыбаюсь
Managed-код бывает разным: safe и unsafe. Unsafe позволяет работать с указателями - тогда ты можешь использовать memcmp из STL. Но, разумеется, это не рекомендуется. А раз в safe-коде нет прямых операций с памятью, то какой из этого следует вывод? (К вопросу о пользе Вирта.)

Могу и прямо спросить: ты вообще алгоритм работы с массивом (а не байтами в памяти) закодировать способен?
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
jur
Помогающий

lt
Offline Offline

« Ответ #8 : 24-05-2014 14:38 » 

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

В первом посте я написал, что имеется бинарный файл моей прошивки для микроконтроллера. Это просто двоичная каша, внутри которой есть "шаблон" серийного номера в виде строки ASCII символов (выглядит так: "0000000AA000"). Вот мне и нужно найти двоичный подмассив из 12-ти символов "0000000AA000" в двоичном массиве прошивки. Потом я заменю эти 12 символов на символы, которые ввел настройщик. Какие тут регулярные выражения?! :-)

К тому же строка в .NET - это не область памяти с произвольными операциями внутри неё, а константа. Любая операция над строкой приводит к копированию исходной и созданию новой модифицированной строки. Именно поэтому практики из языка C в данном случае порочны.

Полностью согласен. Я про строки в C++/CLI уже почитал :-) Мало того, я даже освоил перекодирование строки L"Фирмваре" в "Фирмваре" (с char'ами)! Судя по несметному числу вопросов на эту тему в Интернете, эта задача не из легких :-)

Managed-код бывает разным: safe и unsafe. Unsafe позволяет работать с указателями - тогда ты можешь использовать memcmp из STL. Но, разумеется, это не рекомендуется. А раз в safe-коде нет прямых операций с памятью, то какой из этого следует вывод? (К вопросу о пользе Вирта.)

Совсем ты меня затюкал... Ну скажи, как в этом проклятом C++/CLI найти в двоичном массиве нужные 12 байт и заменить их на другие 12 байт? И при чем тут Вирт?!

Могу и прямо спросить: ты вообще алгоритм работы с массивом (а не байтами в памяти) закодировать способен?

Так, чай, "Не бином Ньютона" (С) :-) Как найти адрес нужной последовательности в массиве байт я показал в примере кода. Про замену этой последовательности на другую последовательность - вообще нечего говорить.

Или ты про сферический массив в вакууме? Так это мне пока как-то без надобности... :-)


Записан

MPEG-4 - в массы!
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #9 : 24-05-2014 15:27 » 

Цитата: jur
Или ты про сферический массив в вакууме? Так это мне пока как-то без надобности... Улыбаюсь
Ну раз без надобности, то и .NET тебе без надобности. Потому что нет никаких адресов, битов и т.п. Есть массив байтов. Или ты пишешь алгоритм работы с массивом, или не пишешь. Дело хозяйское.

Цитата: jur
Ну скажи, как в этом проклятом C++/CLI найти в двоичном массиве нужные 12 байт и заменить их на другие 12 байт? И при чем тут Вирт?!
Нет никакого "двоичного массива", есть массив из байтов - беззнаковые целые числа от 0 до 255 каждое. Вместо байтов могут быть хоть попугаи. Так вот как в одном массиве найти индекс, с которого начинается та же подпоследовательность попугаев, что содержится в другом массиве, и как с этого найденного места заменить одну пачку попугаев на другую?

Это элементарная задача, которую когда-то и школьник 9-го класса решал спокойно. Ты себя пяткой в грудь бил, что это элементарная задача, которую ты на любом языке решишь. Вирт тут при том, что он Pascal придумал и на нём разные алгоритмы отрабатывал - в том числе и этот обсуждаемый. У Вирта он, правда, фигурирует как поиск строки в последовательном файле, но это деталь несущественная. Это всего лишь надо аккуратно написать. Решение на C/C++ будет точно таким же, как в Pascal или в .NET. И никакие функции тут не нужны. Ну удобно будет использовать Array.IndexOf, чтоб лишний цикл не писать.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
jur
Помогающий

lt
Offline Offline

« Ответ #10 : 24-05-2014 15:59 » 

Ну раз без надобности, то и .NET тебе без надобности. Потому что нет никаких адресов, битов и т.п. Есть массив байтов. Или ты пишешь алгоритм работы с массивом, или не пишешь. Дело хозяйское.

Я-ж в самом начале сказал, что жизнь заставила применить .NET. Тут вот в чем дело. Фирма Cypress, микросхему которой мы применяем, дает DLL-ку, позволяющую прошивать фирмваре в их микроконтроллер. Но все дело в том, что эта DLL-ка - совсем не DLL-ка, а .NET Assembly. Писать самому низкоуревневые процедуры прошивки микроконтроллера я посчитал мартышкиным трудом. Использовать их пример на C# я тоже не хочу, т.к. "я шарповыми языками не владею" (С) :-)

Осталось только одно приемлемое для меня решение: написать простую утилитку для настройщиков на C++/CLI. С чем я сейчас и бодяюсь :-)

Цитата: jur
Ну скажи, как в этом проклятом C++/CLI найти в двоичном массиве нужные 12 байт и заменить их на другие 12 байт? И при чем тут Вирт?!
Нет никакого "двоичного массива", есть массив из байтов - беззнаковые целые числа от 0 до 255 каждое.

Для меня "двоичный массив" и "массив из байтов" - синонимы, т.к. двоичный массив именно и состоит из отдельных байтов. Разве не так?!

Это элементарная задача, которую когда-то и школьник 9-го класса решал спокойно. Ты себя пяткой в грудь бил, что это элементарная задача, которую ты на любом языке решишь. Вирт тут при том, что он Pascal придумал и на нём разные алгоритмы отрабатывал - в том числе и этот обсуждаемый. У Вирта он, правда, фигурирует как поиск строки в последовательном файле, но это деталь несущественная. Это всего лишь надо аккуратно написать. Решение на C/C++ будет точно таким же, как в Pascal или в .NET. И никакие функции тут не нужны. Ну удобно будет использовать Array.IndexOf, чтоб лишний цикл не писать.

Так я-ж это и спрашивал! Есть ли в C++/CLI готовая функция, решающая мою задачу поиска. Если нет - так коню понятно, что я ее напишу вручную. Что, собственно, я и показал в примере кода. Ты уж, пожалуйста, не считай меня за последнего идиота, который не способен программно заменить одни 12 байт на другие :-)

Тогда скажи, пожалуйста, другое. Как кошерно получить доступ к исходному массиву в моей функции поиска и замены байт. Оба массива представлены так:

array<System::Byte> ^ Fw_data;
array<System::Byte> ^ SN_data;

Мне представляется, что проще всего было бы создать функцию поиска и замены примерно так:

bool insert_sn( unsigned char* fw_data, int fw_data_len, unsigned char* sn_data, int sn_data_len );

или, т.к. длина сериального номера не меняется и известна, то:

bool insert_sn( unsigned char* fw_data, int fw_data_len, unsigned char* sn_data );

Наверное исходные Fw_data и SN_data следовало бы скопировать в какие-нить массивы (обычного C-шного вида) unsigned char и уже адреса этих массивов передать в функцию? Или еще как?

Записан

MPEG-4 - в массы!
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #11 : 24-05-2014 17:06 » 

Цитата: jur
Для меня "двоичный массив" и "массив из байтов" - синонимы, т.к. двоичный массив именно и состоит из отдельных байтов. Разве не так?!
Какое имеет значение, что там "для тебя", когда в .NET нет двоичных массивов. Вернее, есть BitArray, но тебе это совсем не понравится - это для логических флажков.

Цитата: jur
Есть ли в C++/CLI готовая функция, решающая мою задачу поиска. Если нет
Вроде бы я недвусмысленно сказал, что такая функция для массива вообще (произвольного типа), и тем более коллекции в .NET не имеет смысла. Соответственно, её и нет.

Цитата: jur
Как кошерно получить доступ к исходному массиву в моей функции поиска и замены байт.
Какой-то странный вопрос. Доступ к элементу массива через индекс в квадратных скобках. Размер массива - его свойство Length.

Цитата: jur
bool insert_sn( unsigned char* fw_data, int fw_data_len, unsigned char* sn_data, int sn_data_len );
В .NET нет указателей на области памяти. Вернее тебе, как начинающему, этим пользоваться не рекомендуется. Декларацию массивов ты сам прекрасно знаешь и демонстрируешь. Передавать длину отдельным параметром избыточно - объект массива сам знает свою длину.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
jur
Помогающий

lt
Offline Offline

« Ответ #12 : 24-05-2014 18:05 » 

Цитата: jur
Как кошерно получить доступ к исходному массиву в моей функции поиска и замены байт.
Какой-то странный вопрос. Доступ к элементу массива через индекс в квадратных скобках. Размер массива - его свойство Length.

Я правильно понял, что доступ к массиву с помощью квадратных скобок - нормальная, разрешенная практика?

Цитата: jur
bool insert_sn( unsigned char* fw_data, int fw_data_len, unsigned char* sn_data, int sn_data_len );
В .NET нет указателей на области памяти. Вернее тебе, как начинающему, этим пользоваться не рекомендуется. Декларацию массивов ты сам прекрасно знаешь и демонстрируешь. Передавать длину отдельным параметром избыточно - объект массива сам знает свою длину.

Можно-ли сказать, что не так страшен черт, как его малюют? :-) Если так, то я могу написать простую функцию вроде такой:

bool insert_sn( array<System::Byte>^ fw_data, array<System::Byte>^ sn_data );

А как попроще написать функцию сравнения 12 байт? Что-то типа такого:

bool sn_template_found( array<System::Byte>^ fw_data_fragment, array<System::Byte>^ sn_data );

Тогда в теле функции insert_sn я бы вызывал функцию sn_template_found как-то так:

Код:
bool insert_sn( array<System::Byte>^ fw_data, array<System::Byte>^ sn_data )
{
  int sn_index = -1;

  for(int i = 0;i < (fw_data->Length - sn_data->Length);i++)
  {
    // Не знаю, как правильно задать адрес подмассива fw_data[i] ?
    if( sn_template_found( (array<System::Byte>^) fw_data[i], sn_data ) )
    {
      sn_index = i;
      break;
    }
  }

  if( sn_index != -1 )
  {
    // поместить 12 байт введенного SN в фирмваре и прошить микроконтроллер
  }
}

Выглядит, правда, коряво... И, видимо, параметр fw_data_fragment нужно как-то правильнее подавать? Или городить сравнение 12 байт прямо в теле insert_sn не создавая отдельную функцию? А может в функцию сравнения подавать текущий индекс в fw_data? Еще смущает, что при каждом вызове вроде как создается копия исходного array<System::Byte>, это так? Ведь до хрена лишней работы получается...

Или нужно делать совсем по-другому? (Сложно все в этом .NET-те...)


Записан

MPEG-4 - в массы!
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #13 : 24-05-2014 18:28 » 

Цитата: jur
Я правильно понял, что доступ к массиву с помощью квадратных скобок - нормальная, разрешенная практика?
Прежде чем задавать такие вопросы, ты бы задался вопросом, а где это не так. Улыбаюсь

Цитата: jur
я могу написать простую функцию вроде такой:

bool insert_sn( array<System::Byte>^ fw_data, array<System::Byte>^ sn_data );
Можешь. Только если уж тебе так припёрло .NET-типы использовать, то вместо bool System::Boolean, вместо int System::Int32 и т.д. Хотя это всё одно и то же.

Цитата: jur
// Не знаю, как правильно задать адрес подмассива fw_data ?
Какой адрес подмассива, когда у тебя есть индекс? Вот скажи, чего ты в адреса вцепился как клещ? НЕТ АДРЕСОВ. И нет специально, чтобы не мешать работе менеджера памяти, который память выделяет и освобождает, и даже дефрагментирует, перемещая в ней объекты по своему усмотрению. Адреса - это его интимное дело, а не твоё.

Цитата: jur
Тогда в теле функции
Ну если в лоб делать, то примерно так. Хотя если воспользоваться замыслом Вирта, повторных просмотров можно избежать. У Вирта для этого был мощнейший стимул: он искал строчки в текстовых файлах, записанных на магнитную ленту, скорость работы которой (особенно в режиме рандомного доступа) такова, что разом отбивает охоту к подобным подходам. Сейчас это, конечно, не имеет значения.

Цитата: jur
Еще смущает, что при каждом вызове вроде как создается копия исходного array<System::Byte>, это так?
Конечно нет. Ты же записываешь значок ^ - это аналог указателя в .NET, но без адресной арифметики. Опять же, из области матчасти: есть value-типы (простые и структуры) и reference-типы (классы). Первые передаются по значению, если вручную не задать передачу по ссылке. Вторые всегда передаются по ссылке и по значению их передать невозможно. Array - это класс, следовательно, он всегда ссылочный.
« Последнее редактирование: 24-05-2014 18:32 от Dimka » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
jur
Помогающий

lt
Offline Offline

« Ответ #14 : 24-05-2014 19:05 » 

Цитата: jur
Я правильно понял, что доступ к массиву с помощью квадратных скобок - нормальная, разрешенная практика?
Прежде чем задавать такие вопросы, ты бы задался вопросом, а где это не так. :)

Так черт его знает, этот .NET! В нем все не как у людей! :-)

Цитата: jur
// Не знаю, как правильно задать адрес подмассива fw_data ?
Какой адрес подмассива, когда у тебя есть индекс? Вот скажи, чего ты в адреса вцепился как клещ? НЕТ АДРЕСОВ. И нет специально, чтобы не мешать работе менеджера памяти, который память выделяет и освобождает, и даже дефрагментирует, перемещая в ней объекты по своему усмотрению. Адреса - это его интимное дело, а не твоё.

Так непривычно-ж! К тому же, как-то не очень хочется, чтобы простая функция низкого уровня имела представление о каких-то там массивах с фирмваре. Т.е. верно ли я понимаю, что можно создать функцию поиска N байт в таком виде:

System::Boolean sn_template_found( array<System::Byte>^ array_to_search_in, System::Int32 start_index, array<System::Byte>^ data_to_search );

А при ее вызове, типа:

  if( sn_template_found( fw_data, i, sn_data ) )
  {
     // Подмассив найден
  }

я получу ответ: "Твой гр...й темплейт найден!" или "Твой ср...й темплейт НЕ найден!", верно?

Ну если в лоб делать, то примерно так. Хотя если воспользоваться замыслом Вирта, повторных просмотров можно избежать. У Вирта для этого был мощнейший стимул: он искал строчки в текстовых файлах, записанных на магнитную ленту, скорость работы которой (особенно в режиме рандомного доступа) такова, что разом отбивает охоту к подобным подходам. Сейчас это, конечно, не имеет значения.

Хорошо ему, у него необходимости в .NET не было! :-)

Цитата: jur
Еще смущает, что при каждом вызове вроде как создается копия исходного array<System::Byte>, это так?
Конечно нет. Ты же записываешь значок ^ - это аналог указателя в .NET, но без адресной арифметики. Опять же, из области матчасти: есть value-типы (простые и структуры) и reference-типы (классы). Первые передаются по значению, если вручную не задать передачу по ссылке. Вторые всегда передаются по ссылке и по значению их передать невозможно. Array - это класс, следовательно, он всегда ссылочный.

Да, что-то такое я уже читал. Только много новой информации требует приличного времени, чтобы рассесться в голове "по полочкам" :-) Неделю ковыряюсь всего...

Спасибо за помощь, уважаемый коллега! Появилась надежда, что свою простенькую утилитку я все-таки смогу написать :-)

Последний малюсенький штришок: существует ли возможность в .NET создать файл в памяти (типа RAM-диска)? Гугл говорит, что вроде нет, а на самом деле?...


Записан

MPEG-4 - в массы!
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #15 : 24-05-2014 20:35 » 

Цитата: jur
я получу ответ: "Твой гр...й темплейт найден!" или "Твой ср...й темплейт НЕ найден!", верно?
В .NET нет template, есть generic-типы. Это разные вещи. В C++ код генерируется в момент подстановки template. В .NET generic-тип обрабатывается сразу и проверяется на все случаи, т.е. шаблоном (template) не является.

Цитата: jur
Неделю ковыряюсь всего...
Это странно. Когда я, заранее зная C/С++, 11 лет назад впервые взялся за C# (тогда ещё в ходу была версия 1.0 и только-только вышла 1.1), мне понадобилось часа полтора для уточнения ключевых отличий. Если за неделю нет прогресса, есть сомнения во владении программированием вообще (или программированием без зависимости от языка).

Цитата: jur
существует ли возможность в .NET создать файл в памяти (типа RAM-диска)?
RAM-диск - это не файл. У него есть файловая система, в которой хранятся многие и разные файлы. Файл в памяти создать можно. System.IO.MemoryStream. Только это не файл, а поток - т.е. последовательность байтов с последовательным/блоковым доступом, над которыми определены операции read, write, seek, tell, eof и т.п.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
jur
Помогающий

lt
Offline Offline

« Ответ #16 : 25-05-2014 10:03 » 

Цитата: jur
я получу ответ: "Твой гр...й темплейт найден!" или "Твой ср...й темплейт НЕ найден!", верно?
В .NET нет template, есть generic-типы. Это разные вещи. В C++ код генерируется в момент подстановки template. В .NET generic-тип обрабатывается сразу и проверяется на все случаи, т.е. шаблоном (template) не является.

Нет, нет, я не имел ввиду сишную штуковину template, это я просто просто перевел на "русский" выражение "шаблон - последовательность байт - сериального номера" :-)

Цитата: jur
Неделю ковыряюсь всего...
Это странно. Когда я, заранее зная C/С++, 11 лет назад впервые взялся за C# (тогда ещё в ходу была версия 1.0 и только-только вышла 1.1), мне понадобилось часа полтора для уточнения ключевых отличий. Если за неделю нет прогресса, есть сомнения во владении программированием вообще (или программированием без зависимости от языка).

Значит ты - гениальный программист, телепатически узнавший, как конкретно разрабатывается программа C#, посерьезнее "Хелло Ворлд!", в среде Визуальной Студии. Это надо же, за полтора часа узнать, как конфигурировать среду разработки (например, как включить стороннюю Assembly в свой проект), как строить программу (в том числе из нескольких файлов), как называются и для чего служат тысячи классов и методов среды .NET, и много, много других вещей, нужных не только для понимания "ключевых отличий", а для построения реальных программ. И все это за полтора часа! Браво!! Совершенно выдающийся результат!!! :-)

Цитата: jur
существует ли возможность в .NET создать файл в памяти (типа RAM-диска)?
RAM-диск - это не файл. У него есть файловая система, в которой хранятся многие и разные файлы. Файл в памяти создать можно. System.IO.MemoryStream. Только это не файл, а поток - т.е. последовательность байтов с последовательным/блоковым доступом, над которыми определены операции read, write, seek, tell, eof и т.п.

Неужели я так непонятно выражаюсь?! Я ведь не говорил, что RAM-диск - это файл. Я сказал, что хотел бы создать файл в памяти, а не на каком-то дисковом устройстве (хард-диск, флэш-диск и <тому_подобный>-диск). MemoryStream, не MemoryStream - мне все равно. Может подойдет Memory mapped file. Мне нужно, чтобы можно было получить path к этому файлу, каковой путь я могу передать методу записи двоичных данных в микроконтроллер. Спасибо, за подсказку, поковыряюсь в этом направлении.

P.S. Прошу перестать втаптывать меня в грязь потому, что с непонятными для меня вопросами я обратился в раздел "Учимся программировать > Начинающим". Я ведь не "Гениальный Программист" (TM), а обычный прикладник, решающий свои приземленные, практические задачи. Пожалуйста, смотри на меня снисходительнее со своего Олимпа...


Записан

MPEG-4 - в массы!
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #17 : 25-05-2014 14:01 » 

Цитата: jur
Это надо же, за полтора часа узнать, как конфигурировать среду разработки (например, как включить стороннюю Assembly в свой проект), как строить программу (в том числе из нескольких файлов)
Навыки работы с Visual Studio к .NET отношения не имеют. Потому как самые сложные настройки - это как раз C++ без всякого .NET, если ты хорошо знаешь, как и что в нём настраивается, остальное - сущая безделица.

Цитата: jur
как называются и для чего служат тысячи классов и методов среды .NET
Тысячи классов для решения твоей задачи не нужны. И не только в твоей задаче, но и в 100% всех остальных задач, с которыми сталкивается разработчик.

Цитата: jur
Может подойдет Memory mapped file. Мне нужно, чтобы можно было получить path к этому файлу, каковой путь я могу передать методу записи двоичных данных в микроконтроллер.
Бредятина какая-то. Файловая система - это в общем случае иерархическая база данных, где каждая порция данных поименована и уникальным образом идентифицируется через path, что позволяет не зависеть от физических адресов расположения данных: path есть ключ к адресу данных. В работающей программе никакие path не нужны по той причине, что достаточно дать прямую ссылку на нужные данные. В данном случае передать объект по ссылке через аргумент функции.

Цитата: jur
Прошу перестать втаптывать меня в грязь потому, что с непонятными для меня вопросами я обратился в раздел "Учимся программировать > Начинающим".
Падаван, как только прекратятся "заявления с апломбом" с твоей стороны - так сразу. Отлично
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
jur
Помогающий

lt
Offline Offline

« Ответ #18 : 25-05-2014 18:51 » 

Падаван, как только прекратятся "заявления с апломбом" с твоей стороны - так сразу. Отлично

Где ты увидел "заявления с апломбом" в моих словах - велика тайна сия есть... Ну да ладно... Просто сейчас я вижу, что нормально соображающий человек мог бы ответить на мой первый пост двумя предложениями:

1. Ты неправильно понял имя метода "BinarySearch", это метод поиска, а не аналог strstr или memcmp из обычного С.
2. Для решения твоей задачи в среде .NET нет готовой функции/метода, но очень просто сделать аналог strstr самому, используя кошерный доступ к элементам твоего двоичного массива с помощью [].

И все. И не нужно кучи наукообразных слов, никчемных замечаний, оскорблений незадачливого новичка в .NET, неосторожно попавшегося тебе под руку. И, конечно, для решения такой простой задачи не нужно никакого Вирта...

P.S. Конечно, когда я узнал, что двоичные массивы можно спокойно передавать в свои функции и можно обращаться к их элементам с помощью старых, привычных скобок [], я легко и непринужденно решил свою задачу. Спасибо за полезные подсказки.


Записан

MPEG-4 - в массы!
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #19 : 25-05-2014 19:16 » 

Цитата: jur
Для решения твоей задачи в среде .NET нет готовой функции/метода
Что есть, и чего нет в .NET, достоверно не знает никто - это неправильная постановка вопроса. Если кто-то знает, он это показывает, если кто-то не знает - он молчит. Если кто-то заявляет, что "нет такого" - это как раз пример "заявления с апломбом".

Цитата: jur
Ты неправильно понял имя метода "BinarySearch", это метод поиска, а не аналог strstr или memcmp из обычного С.
Чтобы я с тобой так разговаривал, требуется, чтобы и ты вопросы задавал тоже кратко, по существу и в деловом стиле. А не "живописал" "мелодрамы", как ты ресурсы добавлял, и в каких цветах тебе представляется .NET.

Коротко говоря, какой вопрос, такой и ответ.

Цитата: jur
И все. И не нужно кучи наукообразных слов, никчемных замечаний, оскорблений незадачливого новичка в .NET
Справедливо: действительно, зачем куча слов и утверждений, когда можно задать вопрос в одну строчку и по существу дела?

Цитата: jur
Конечно, когда я узнал, что двоичные массивы можно спокойно передавать в свои функции и можно обращаться к их элементам с помощью старых, привычных скобок [], я легко и непринужденно решил свою задачу.
Белые люди сперва пробуют самые очевидные вещи, и только когда их собственные идеи исчерпаны, ходят на форумы задавать вопросы. В противном случае это лишь желание потрепаться, а не желание по-деловому решить свою проблему. Ну вот и потрепались на целую страницу, хотя всё могло бы ограничиться двумя постами, а то и вообще тему создавать не потребовалось бы.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
jur
Помогающий

lt
Offline Offline

« Ответ #20 : 26-05-2014 21:15 » 

Чтобы я с тобой так разговаривал, требуется, чтобы и ты вопросы задавал тоже кратко, по существу и в деловом стиле.

Ты, видать, по техническим форумам редко ходишь, раз так говоришь :-) Я тебя просвещу в этом вопросе. Особенно мои слова актуальны для зарубежных форумов (из последних - фирмы Cypress например. Я их спецов нехило мытарил...).

Вот заводишь ты тему, к примеру, "C++/CLI Как использовать BinarySearch?". В теле сообщения пишешь кратко, по существу, в деловом стиле: "Как найти последовательность символов "0000000AA000" в данных?". Предполагается что, как это было в моем случае, ты ошибочно истолковал слово "BinarySearch", думая, что это поиск двоичных данных.

И понеслась! :-))

Тебе начнут предлагать:

- Ищи с помощью функции String::Compare.
- Отсортируй массив и ищи в нем.
- еще масса вариантов, на которые мне фантазии не хватает :-)

Обескураженный, ты пытаешься понять, что тебе говорят умные люди (не забывай, предполагается, что ты новичок). В следующем посте ты робко уточняешь, что искать строку "0000000AA000" нужно в двоичных данных. Тебе опять предлагают:

- Ищи с помощью функции String::Compare. (Да, да, продолжат повторять то же самое :-))
- Отсортируй массив и ищи в нем.
- еще масса вариантов, на которые мне фантазии не хватает :-)

Ты упорен, не сдаешься, продолжаешь уточнять: массив, в котором следует искать "0000000AA000", двоичный. Его нельзя сортировать. Число предлагаемых вариантов немного уменьшится, однако их осмысленность тоже, возможно, ухудшится. Добавятся предложения решить твою задачу на Питоне, ПХП, ЛУА, линуксоиды подтянутся :-)

Однако, твое упорство сделано из стали! Ты продолжаешь уточнять: искать нужно в двоичном массиве и искать нужно строку "0000000AA000", состоящую из байтов, а не юникодных символов, про которые думали 99.99% отвечающих.

Последует постепенное дрейфование старт-топика совсем уж в глухие дебри. Я не удивлюсь, если беседа начнет касаться вопросов: "Есть ли жизнь на Марсе?" и "Не противоречит ли однополая любовь парадигме ООП-программирования?" :-)

Дальше твою эпопею расписывать не буду, но уверен: скучно не будет! :-)

Так вот. Умудренный опытом подобного общения, я всегда стараюсь расписать свою проблему наиболее детально и подробно. А чтобы читающему не было скучно, оживляю свое сообщение нормальной, человеческой речью :-) Согласись, читать нудное послание какого-нить косноязычного техно-сухаря совсем не интересно. А если он еще не способен изложить свои мысли "на бумаге", да еще грамотность его на уровне московского таджика-таксиста - то вообще труба... (Таджиков прошу не обижаться, ничего против этих славных людей не имею, просто привел пример из московских СМИ, где таджиков частенько упоминают в контексте плохого знания русского языка. Пожалуйста, не обижайтесь!)

P.S. Я свою задачу решил успешно. Спасибо за подсказки. Возникли другие вопросы, но их я изложу (если не найду решения сам) в отдельных темах. И, ты уж не обессудь, распишу их во-возможности наиболее детально, с освещением необходимого контекста. Хотя сделать это в самом первом сообщении часто бывает совсем не легко...

P.P.S. "Будь проще! И к тебе потянутся люди!" (С) :-)


« Последнее редактирование: 26-05-2014 21:18 от jur » Записан

MPEG-4 - в массы!
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #21 : 26-05-2014 21:55 » 

jur, совет работать со строкой, кстати, имеет право на жизнь. Только для этого потребуется байты сперва сконвертировать в char, а затем обратно. И уже получив массив char, превратить его в строчку, после чего найти в ней искомое элементарным регулярным выражением.

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


Опять же, белые люди сперва пробуют решить задачу так, как умеют (т.е. не зная библиотек, пишут алгоритмы сами, особенно простые алгоритмы). И только потом, когда задача решена, сроки не горят и т.п., могут задаться вопросом, а как это можно улучшить или заменить на какое-нибудь стандартное решение.


А в целом народная мудрость не зря гласит, что правильно заданный вопрос содержит половину ответа. Здесь "больше слов" не значит "лучше для понимания".
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
jur
Помогающий

lt
Offline Offline

« Ответ #22 : 27-05-2014 21:38 » 

jur, совет работать со строкой, кстати, имеет право на жизнь.

Не имеет. Однозначно. Дело-то в том, что массив, в котором следует искать подстроку, является "двоичной кашей" (фирмваре, двоичный образ программы микроконтроллера). Первый же встреченный в нем ноль определит конец строки. Все, финиш. Задача не решена.

Если же "двоичную кашу" превратить в представимый в строке вид данных - вообще хрен знает, что получится. Да и зачем?! Поиск двоичного подмассива в двоичном массиве осуществляется легко и просто, когда знаешь, как это делается :-)

Поэтому в данном случае единственно верный путь - это искать двоичную последовательность "0000000AA000", представленную в виде массива char-ов (т.е. 8-битных байт) в большом двоичном массиве, представляющим образ фирмваре. Благодаря твоим дельным подсказкам, мне удалось успешно решить эту задачу, далеко не очевидную для новичка в .NET. Сама задача ни малейших трудностей не представляет, но сложность тут в том, что, как ты верно заметил, нет никаких адресов, поинтеров, и т.п. Использование [] и простого индекса позволили разобраться с проблемой и устранить ее.

Спасибо за дельные подсказки! Данную тему считаю благополучно решенной, но на очереди еще немало других :-) В случае неуспеха самостоятельного нахождения решения, буду порождать новые темы :-) (Вы так просто от меня не отделаетесь! :-))


Записан

MPEG-4 - в массы!
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #23 : 27-05-2014 22:38 » 

Цитата: jur
Первый же встреченный в нем ноль определит конец строки.
И это было ещё одно "заявление с апломбом" при полном незнании матчасти .NET.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #24 : 27-05-2014 23:05 » 

Да не, Дим, вот это весчь!

8-битных байт

 Жжешь Внимание! Говорит и показывает... RTFM
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
jur
Помогающий

lt
Offline Offline

« Ответ #25 : 28-05-2014 17:49 » 

Да не, Дим, вот это весчь!
8-битных байт

:-)

Смейтесь, смейтесь! Однако, более чем в одной классической книге, посвященной программированию, указывается что-то типа: "мы будем рассматривать байт, как порцию двоичных данных, состоящую из 8 бит" :-) К сожалению, затрудняюсь привести авторов и названия этих книг (многих из которых, увы, я уже не имею на своей полке...), но сие врезалось в память.

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

P.S. Ребята, мне очень нравится общаться в свободном, неформальном стиле! :-) Всегда считал и считаю, что участники любого форума - нормальные люди, ценящие общение друг с другом. Однако сильно опасаюсь санкций от Господина Модератора, который, возможно, не разделяет моего восторга от беседы, отклоняющейся от топика исходного сообщения. Поэтому, будучи просто рядовым участником форума, увы, задвигаю молнию, запирающую мой фонтан красноречия, в закрытое положение! :-)

P.P.S. Сейчас бьюсь на другой тривиальнейшей задачей: получить в Визуальной Студии 2008 хэндл текущего приложения (проект - обычное Dialog Based MFC-приложение).  (Точнее, мне нужно работать с двоичными данными, "уложенными" в ресурсы приложения.) Знаю, что задача элементарнейшая, но как это делается - вылетело из головы. А поиск в Гугле выдает многие миллионы ссылок, несколько десятков первых страниц которых не имеет вообще ничего общего с моим вопросом: "How to get handle of running application". Пока пытаюсь вспомнить/найти решение самому... :-)

P.P.P.S. Ковыряюсь в направлении GetCurrentProcess(), который выдает "псевдо хэндл". Посмотрю, что получится...

P.P.P.P.S. Да, совсем не сложно:

Код:
  HRSRC res       = FindResource(NULL, MAKEINTRESOURCE(IDR_BINARY_DATA), "BINARY");
  DWORD res_size  = SizeofResource(NULL, res);
  HGLOBAL res_bin = LoadResource(NULL, res);
  BYTE*   res_ptr = (BYTE*)LockResource(res_bin);
  // работаем с двоичными данными нашего ресурса
  FreeResource(res_bin);


« Последнее редактирование: 28-05-2014 19:32 от jur » Записан

MPEG-4 - в массы!
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #26 : 28-05-2014 18:48 » 

Чем тебе псевдохэндл не нравится? Он работать приложению с собственным процессом никак не мешает.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
jur
Помогающий

lt
Offline Offline

« Ответ #27 : 28-05-2014 19:36 » new

Чем тебе псевдохэндл не нравится? Он работать приложению с собственным процессом никак не мешает.

Да, я уже понял свою "загогулину" :-) Еще не видел этого твоего сообщения и отредактировал предыдущее свое. Мне, в общем-то, хендл приложения не нужен, мне нужно выковырять из экзешника двоичные ресурсы. Как я и предполагал, "как два пальца" :-)

Большое спасибо за подсказку! Возможно в будущем мне и хендл процесса тоже понадобится.


Записан

MPEG-4 - в массы!
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines