Hatred's Log Place

DON'T PANIC!

Jan 17, 2012 - 1 minute read - Comments - life linux

Amp, a layer3 player

Накатило, решил найти исходники этой программки. Что делает? Да просто берёт и играет mp3 файл. Чем знаменита? :) А тем, что это мой первый проигрыватель mp3 на Linux, который попался мне случайно на купленном диске во Владивостоке, во времена, когда у меня не было интернета и в своём городе-посёлке я был единственным пингвиноводом.

(на этом сайте) | Source2 | Где найдено

Никаких внешних зависимостей, исходники на чистом Си, в распакованном виде - 290Кб.

PS при сборке на современных системах нужно будет применить такой патч:

--- /home/hatred/download/tmp/mp3/amp-0.7.6/guicontrol.c	1997-08-23 22:30:51.000000000 +1100
@@ -375,7 +375,8 @@
 	break;	
       case GETHDR_SYN: warn("oops, we're out of sync.<br/>n");
 	break;
1.      default: 
+      default:
+        ;
       }
       break;
     }

по сути, после default:, поставить точку с запятой :simple_smile:

Jan 12, 2012 - 2 minute read - Comments -

DokuWiki, BlogTNG, плагин googleplusone и доработка шаблона

Что бы при использовании плагина googleplusone совместно с BlogTNG при попытке “поделиться” постом в Google+ вставлялся не абы какой текст, а то, что вам нужно, следует внести некоторые модификации в используемый вами шаблон.

Dec 13, 2011 - 1 minute read - Comments - programming c++

Boost, CMake, кросскомпиляция

  • Q: Boost.Asio - что нужно указать в cmake среди компонентов при поиске библиотеки boost?

    A: только библиотеку system:cmakefind_package(Boost REQUIRED COMPONENTS system)

  • Q: Boost.Thread и кроскомпиляция - что делать, если получаем ошибку вида: **undefined reference toboost::tss_cleanup_implemented()'**?<br/><br/> **A:** для начала чуток обратно: в случае Linux, в качестве компонента при поиске библиотеки нужно указыватьthread, а в случае windows (и кроскомпиляции):thread_win32, т.е. необходимо писать что-то вроде такого кода:``cmake set(BOOST_COMPONENTS program_options system )

    Boost thread library is different on Win/Linux

    if(WIN32) set(BOOST_COMPONENTS ${BOOST_COMPONENTS} thread_win32) else() set(BOOST_COMPONENTS ${BOOST_COMPONENTS} thread) endif()

find_package(Boost COMPONENTS ${BOOST_COMPONENTS} REQUIRED) Подсказку увидел тут: [http://lists.gnu.org/archive/html/mingw-cross-env-list/2010-11/msg00063.html](http://lists.gnu.org/archive/html/mingw-cross-env-list/2010-11/msg00063.html). Так же следует добавить следующее (при статической линковке):cmakeadd_definitions(-DBOOST_THREAD_USE_LIB=1) . Далее, собственно, относительно самого вопроса, предлагают в случае появления такой ошибки при компиляции, поместить в любой свой исходник следующее:cpp namespace boost { void tss_cleanup_implemented() { } } ``` чистой воды хак :) Дополнительно написано тут: http://solarcore.blogspot.com/2010/10/boost-c-threads-mingw-mac-os-x.html

Dec 13, 2011 - 2 minute read - Comments - programming

MinGW: кросс-отладка win32 приложений в Linux

По сути парочка дополнений для этой статьи: http://mingw-cross.sourceforge.net/cross_debug.html

Задача: есть win32 приложение, собранное путём кросс-компиляции при помощи cmake и mingw32, нужно запустить его в отладчике и поймать на чём оно падает.

Необходимый инстументарий: 1. установленный mingw32 2. wine (winconsole) 3. бинарная версия gdb для windows, брать тут:

http://sourceforge.net/projects/mingw/files/MinGW/Extension/gdb/ 4. версия gdb, собранная для Linux, знающая как подгружать win32 приложения, собранные mingw. Тут нужно искать сборку для вашего дистрибутива, для пользователей ArchLinux я сделал PKGBUILD и поместил его в AUR:

https://aur.archlinux.org/packages.php?ID=54802

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

Бинарную версию нужно будет распаковать, например в ~/bin/mingw32-gdb-win32/. В директорию ~/bin/mingw32-gdb-win32/bin/ при этом следует сделать следующие симлинки:

cd ~/bin/mingw32-gdb-win32/bin/
ln -s /usr/i486-mingw32/bin/libexpat-1.dll .
ln -s /usr/i486-mingw32/bin/libiconv-2.dll .
ln -s /usr/i486-mingw32/bin/libintl-8.dll .

Всё. Впринципе всё готово для отладки.

  1. Запускаем сервер:```bash wineconsole cmd /K ~/bin/mingw32-gdb-win32/bin/gdbserver.exe localhost:6000 test-app.exe [аргументы для программы с которыми она должна запускаться]

    1. Запускаем клиент gdb:```bash
    i486-mingw32-gdb test-app.exe
  2. В запущенной версии gdb выполняем следующую команду:gdb (gdb) target remote localhost:6000

    Ну и по сути всё, дальше делаем всё как при обычной отладке при помощи gdb, устанавливаем точки останова, смотрим данные, делаем бектрейсы и т.д. Единственная разница, что для запуска приложения нужно использовать не команду run, а команду continue, но собственно если забудете или перепутаете - отладчик вам подскажет.

    Если программа что-то выбрасывает на консоль, вы увидете это в окне wineconsole.

    Если захочется графической отладки, смотреть в сторону ddd и ссылку, что я давал в начале поста.

Dec 13, 2011 - 1 minute read - Comments - programming c++

inet_aton для windows

Если коротко: функиця заполняет структуру типа in_addr, преобразуя сведения о хосте из строкового представления.

У winsock2 нет такой функции. Есть более продвинутый аналог inet_pton, в POSIX он тоже есть, да вот только mingw про неё в windows не знает. Пичалька.

Поэтому делаем примерно следующее:

#ifdef WIN32
static int inet_aton(const char *cp, struct in_addr *inp)
{
    if (cp == 0 || inp == 0)
    {
        return -1;
    }
    
    unsigned long addr = inet_addr(cp);
    if (addr == INADDR_NONE || addr == INADDR_ANY)
    {
        return -1;
    }
    
    inp->s_addr = addr;
}
#endif

не верх совершенства и корректности, но для моих целей работало.

Dec 13, 2011 - 1 minute read - Comments - programming c++

winsock2: неблокирующийся сокет

    unsigned long arg = 1;
    ioctlsocket(sockfd, FIONBIO, &arg);

в Linux:

    int arg = fcntl(sockfd, F_GETFL, NULL);
    arg |= O_NONBLOCK;
    fcntl(sockfd, F_SETFL, arg);

или универсальная функция:

void setSockNonblock(int sockfd)
{
#ifdef WIN32
    unsigned long arg = 1;
    ioctlsocket(sockfd, FIONBIO, &arg);
#else
    int arg = fcntl(sockfd, F_GETFL, NULL);
    arg |= O_NONBLOCK;
    fcntl(sockfd, F_SETFL, arg);
#endif
}

Dec 13, 2011 - 1 minute read - Comments - programming c++

Альтернативная сборка MinGW

Занимаясь разработкой небольшой программы, использующей сокеты, потоки и не использующей фреймворков, типа Qt, столкнулся с необходимостью собрать это дело для Windows. Подводных камней оказалось много, как результат познакомился с такими милыми сущностями, как Boost.Thread и Boost.Asio.

Но тут вспомнилось, как мне уже приходилось собирать под Windows окружение, для компиляции исходников, использующих Boost и стало грустно. Грустно настолько, что оказалось проще сделать бинарники путём кросс-компиляции. И вот, когда дело было сделано, натыкаюсь на этот ресурс:

http://nuwen.net/mingw.html

Стефан (автор этого поделия) предоставляет сборку MinGW включающую сам компилятор, набор полезных библиотек (включая Boost 1.47.0!) и некоторых полезных утилит. Пакет не требует установки, просто распаковываем в c:
mingw и пользуемся.

Так что на будущее, буду пробовать.

Dec 13, 2011 - 1 minute read - Comments - programming c++

Таймеры в Windows

Внезапно, правда? :)

Но волей судеб нужно было портировать программку, в которой использовался nanosleep(2). И…

Для внезапно стало откровением: В WINDOWS НЕТ ТАЙМЕРОВ ВЫСОКОГО РАЗРЕШЕНИЯ. А есть только по сути хаки и вызов Sleep, с минимальным промежутком в 10мс.

Наиболее часто рекомендуемый вариант:

void sleep_nsec(int64_t interval)
{
    int64_t time1 = 0, time2 = 0, sysFreq = 0;

    QueryPerformanceCounter((LARGE_INTEGER *) &time1);
    QueryPerformanceFrequency((LARGE_INTEGER *) &sysFreq);

    do
    {
        QueryPerformanceCounter((LARGE_INTEGER *) &time2);
    } while(((time2-time1)*1000.0*1000.0/(double)(sysFreq)) < interval);
}

Но тут мы упираем процессор в полку. Есть вариант с использованием select, но, по отзывам, он так же может ждать не менее 10мс.

Т.е., по сути, это единственный вариант для Windows, да ещё и не лишённый глюков: почти все процессоры уже умеют автоматическое понижение частоты… Чуете? Пока работает цикл, значение sysFreq может измениться (поправьте меня, если я не прав) и время потекло.

Кроме того, наткнулся на статью:

http://www.codeproject.com/KB/system/timers_intro.aspx - Timers Tutorial

Описываются различные вариант таймеров: стандартные win32, мультимедийные, Waitable Timers (не знаю как лучше перевести на русский язык), Queue Timers. Но опять таки, все периоды - миллисекунды.

Dec 12, 2011 - 1 minute read - Comments - programming

Qt Creator & doxygen

Сегодня пролетело в рассылке: > Hi, > > Qt Creator master has recently got a feature, which has been requested a > few times, for Doxygen blocks generation. If you type /** or /*! and > press enter/return before a declaration, you’ll get something like: > cpp-qt /*! * * <br/>param data * <br/>param options * <br/>return */ QString generate(const Data &data, const Options &options); > You can also opt whether or not you want an additional <br/>brief command > and leading asterisks for comment continuation (when breaking lines). > The options are in Text Editor->Completion->Documentation Comments. > > Notice that the style is identified from the comment beginning. If you > start it with /*! then the Qt style is used. Otherwise, the Java style > with the @ prefix for the commands is picked. > > Cheers, > Leandro

Проверил - работает, удобно :)