Динамический буфер для работы с объектами winapi.

Тема в разделе "WASM.WIN32", создана пользователем Andrey_59, 23 авг 2023.

  1. Andrey_59

    Andrey_59 Member

    Публикаций:
    0
    Регистрация:
    20 фев 2021
    Сообщения:
    81
    Здравствуйте! Хочется спросить вот о чём, программируя в winapi чтобы считать строку, например, из Listbox нужно выделять массив зачастую довольно большого размера, что не всегда удобно и расточительно(на мой взгляд) из чего возникает вопрос, а возможно ли контейнеры С++ приспособить для этого, допустим istringstream или ostringstream(или что в этом роде) я пробовал, но у меня ничего не вышло. Возможно, кто-то уже задавался этим вопросом я даже в этом уверен что кто-то им задавался, если есть решения, не слишком геморное, то хотелось бы о нём узнать.
     
  2. mantissa

    mantissa Мембер Команда форума

    Публикаций:
    0
    Регистрация:
    9 сен 2022
    Сообщения:
    155
    ты сможешь получить данные только так, как написано в API, тебе все равно придется создавать буфер, чтобы поместить туда данные, потом их этих данных можешь уже сделать объекты в C++ и почистить буфер из памяти, но его все равно выделять придется
     
    Andrey_59, Mikl___ и UbIvItS нравится это.
  3. alex_dz

    alex_dz Active Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    449
    Ежели строки в листбоксе - статика, можно наперед аллоцировать массив и без динамической аллокации обойтись передавая указатель на статик буфер в памятиче
    иначе да.. придется динамицировать
     
    UbIvItS нравится это.
  4. Andrey_59

    Andrey_59 Member

    Публикаций:
    0
    Регистрация:
    20 фев 2021
    Сообщения:
    81
    Думаю, что это уже чистой воды гемморой, если я правильно понял. Если я сейчас делаю так:
    Код (C++):
    1. const int MAX_SIZE = 1024;
    2. TCHAR szBuffer[MAX_SIZE];
    3. SendMessage(hListbox, LB_GETTEXT, idx, (LPARAM)szBuffer);
    А хотелось бы, как то вот так:
    Код (C++):
    1. istringstream is;
    2. SendMessage(hListbox, LB_GETTEXT, idx, (LPARAM)is.str().c_str());
    Вы же предлагаете, насколько я понял, делать так:
    Код (C++):
    1. LRESULT lenString = SendMessage(hListbox, LB_GETTEXTLEN, idx, 0L);
    2. TCHAR* szBuffer = new[lenString+1];
    3. LRESULT len = SendMessage(hListbox, LB_GETTEXT, idx, (LPARAM)szBuffer);
    4. szBuffer[len] = '\0';
    5. delete[] szBuffer;
    Но это же ресурсозатратно постоянно выделять и освобождать память. Можно создать самопальный буффер(точнее попытаться создать), но вот как работает сообщение LB_GETTEXT, как оно внутри считывает, как работает с памятью...
     
  5. mantissa

    mantissa Мембер Команда форума

    Публикаций:
    0
    Регистрация:
    9 сен 2022
    Сообщения:
    155
    а как еще? все эти буферы это просто обертка с удобными методами для работы, внутри все равно память выделяется, просто жизненный цикл объекта легко контролируется. Если память на пару инструкций выделить, то ничего страшного не случится, можете ее кусками выделять, хоть по 1 байту, если ресурсы ограничены, но это будет работать очень медленно, надо выбирать, что важнее, скорость или место в памяти
    --- Сообщение объединено, 24 авг 2023 ---
    оно никак по сути и не работает, оно просто берет текст с окна и через strcpy копирует его в буфер на который указывает аргумент LPARAM
     
  6. Andrey_59

    Andrey_59 Member

    Публикаций:
    0
    Регистрация:
    20 фев 2021
    Сообщения:
    81
    Это понятно, что память внутри всех этих объектов выделяется, но я же показал, что я бы хотел получить, просто не выделять под массивы память, которая будет не востребована. Короче говоря можно функцию написать, которая внутри будет это проделывать, так гораздо легче, чем писать буфер, который сможет работать с этими объектами winapi, к тому же не ясно, как это сделать.

    Тем более, если так, то тут без заранее созданного массива или выделенной памяти ничего не выйдет.
     
  7. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.323
    Добро пожаловать в реальный мир. Если хочешь держать все в С++ контейнерах, бери контейнер, который позволяет тебе выделить пустой буфер и передавай указатель на этот буфер вместе с его размером в соответствующую функцию. Типа как у std::vector есть reserve и &vector[0], или как там у вас Плюсовых хипстеров это называется...

    Ну или ты можешь поехать в Индию, стать аутсорсером мелкомягких и переписать им все апишки с Цэ на Плюсы.
     
    M0rg0t нравится это.
  8. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.243
    чой-то ты совсем дурью страдаешь :) ну-ежли тебе так важен лишний кб озу/кэша - пиши консоли.. вин32 вполне добротная штука именно в плане экономии ресурсов и именно поэтому его писали сугубо сишечкой. глянь ту же нт 4.0 :)
     
    Application нравится это.
  9. Andrey_59

    Andrey_59 Member

    Публикаций:
    0
    Регистрация:
    20 фев 2021
    Сообщения:
    81
    С чего это вдруг я хипстер?!

    И как это сделать, если в параметрах указывается только буфер, размер буфера куда запихнуть прикажете, и причём тут vector тогда уж лучше использовать string, но это исключительно моё предположение. Для форматирования строк и прочих безобразий с символьными данными, насколько я знаю, в с++ предусмотрены istringstream, ostringstream.

    Уже мчусь, аж шуба заворачивается.:yes3: Я бы попробовал написать что-то похожее на listbox исключительно в познавательных целях, но, пожалуй, это слишком для меня.
    --- Сообщение объединено, 25 авг 2023 ---
    Ага экономная... одно окно без всего под 30-50 Кб весит, очень экономно.

    А?! :blush2:
     
  10. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.323
    Взять и передать буфер и размер буфера.
     
  11. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.243
    https://en.wikipedia.org/wiki/Windows_NT_4.0
    это размер стандартных либ, кои пихаються в приложуху.. можно собрать без них, но придётся прописывать свою либу для вызова тех же апишек + на аномальный экзешник могут агриться аверки - стоят ли 3-4кб того??? :)
     
  12. Andrey_59

    Andrey_59 Member

    Публикаций:
    0
    Регистрация:
    20 фев 2021
    Сообщения:
    81
    Т.е. объединить их, скажем, в структуру, так что ли?
    --- Сообщение объединено, 25 авг 2023 ---
    Ну не знаю, возможно, стоит.

    Стоит хотя бы для того чтобы узнать, что это за зверь такой "агриться", "аверки":derisive:

    Даже так..., и как это делается, никогда с таким не сталкивался.
    --- Сообщение объединено, 25 авг 2023 ---
    Там всё на буржуинском...:)
     
  13. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.243
    https://stackoverflow.com/questions/437685/reduce-windows-executable-size
    привыкай юзать/использовать аглицкий - сильно облегчает житуХУ :)
    агриться - сердиться, аверка - антивирус :)
    на плюсах пиши свой класс, кой может выделять буфер, можно прям систему управления памятью прописать. но в итоге у тебя будет оверхед (избыточное использование) по памяти + появятся весёлые ошибки.. к примеру, гонка потоков, использование убитого буфера, слишком малый буфер да прочая лабуда. короче, выигрыша по памяти и скорости едва ли получишь, а гемору получишь много :)
     
    MaKsIm и Marylin нравится это.
  14. Application

    Application Active Member

    Публикаций:
    1
    Регистрация:
    15 окт 2022
    Сообщения:
    110
    В современных реалиях, где картинка может весить по 5 мб,
    30-50, даже 100 кб для ехе не так критично, разве нет?

    Главное чтобы не было веселых, трудно-улавливаемых ошибок.
     
    Последнее редактирование: 25 авг 2023
    Marylin нравится это.
  15. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.323
    Не понимаю, что непонятного. Объявил экземпляр класса, проинициализировал, выделив с его помощью буффер, передал буффер и размер в функцию, определил сколько получилось данных, обрезал буффер до длины данных, вернул куда тебе нужно.
     
  16. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.243
    ваще, коли уж пошла такая пьянка..
    Код (C++):
    1. #include <iostream>
    2. void *buff(int size) {
    3.     int *p = new int[size];
    4.     return p;
    5. }
    6. int main(int argc, char* argv[]){
    7.     int *p = (int*)buff(4);
    8.     auto i = 15;
    9.     p[i] = 7;
    10.     int d = p[i];
    11.     printf("*p[%d]: %d", i, d);
    12. }
    вот она - настоящая динамика :grin:
     
  17. M0rg0t

    M0rg0t Well-Known Member

    Публикаций:
    0
    Регистрация:
    18 окт 2010
    Сообщения:
    1.576
    Используйте сишарп или подобное, там можно.
     
    mantissa нравится это.
  18. alex_dz

    alex_dz Active Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    449
    у вас крешняк намечается на строке №9 да и 10 тож :)
     
  19. MaKsIm

    MaKsIm Member

    Публикаций:
    0
    Регистрация:
    11 фев 2008
    Сообщения:
    94
    Подозреваю, что на 7 строке просто забыли нолик.