Занимаясь разработкой небольшой программы, использующей сокеты, потоки и не использующей фреймворков, типа Qt, столкнулся с необходимостью собрать это дело для Windows. Подводных камней оказалось много, как результат познакомился с такими милыми сущностями, как Boost.Thread и Boost.Asio.
Но тут вспомнилось, как мне уже приходилось собирать под Windows окружение, для компиляции исходников, использующих Boost и стало грустно. Грустно настолько, что оказалось проще сделать бинарники путём кросс-компиляции. И вот, когда дело было сделано, натыкаюсь на этот ресурс:
http://nuwen.net/mingw.html
Стефан (автор этого поделия) предоставляет сборку MinGW включающую сам компилятор, набор полезных библиотек (включая Boost 1.47.0!) и некоторых полезных утилит. Пакет не требует установки, просто распаковываем в c:
mingw и пользуемся.
Так что на будущее, буду пробовать.
Внезапно, правда? :)
Но волей судеб нужно было портировать программку, в которой использовался
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. Но опять таки, все периоды - миллисекунды.
Сегодня пролетело в рассылке:
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:
/*!
*
* <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
Проверил - работает, удобно :)
Шаг 1. Взять sqlite-jdbc отсюда:
http://www.xerial.org/trac/Xerial/wiki/SQLiteJDBC или при помощи Maven (описание по той же ссылке)
Шаг 2. Положить у себя в проект класс SQLiteDialect, взятый отсюда:
http://arnoraps.tweakblogs.net/blog/3146/hibernate-with-sqlite.html или из архива отсюда:
http://code.google.com/p/hibernate-sqlite/ (HibernateSQLite.zip)
Шаг 3. В конфигурацию Hibernate добавить примерно следующее: ```xml
org.sqlite.JDBC
jdbc:sqlite:./data.db
ru.sincore.db.SQLiteDialect
…
На правах заметки:
- Список зависимостей для Maven, что бы получить последнюю (8.0.4) версию embedded Jetty и получить рабочий JSP.
- Конфиг для embedded Jetty, что бы завёлся JSP.
Подробности подкатом
Отличный, по моему мнению, туториал по Hibernate:
особенно хорошо показаны построения отношений между таблицами.
В последней Java6 не включена tzdata с информацией о том, что в России, сейчас нет перехода на зимнее время. Дальнейшие пояснения излишни.
Как фиксить? Обновить tzdata при помощи предлагаемой ораклом утилиты:
После очередного обновления, заметил, что Опера перестала стартовать. При запуске из терминала, вываливает следующее:
$ opera
(opera:13093): Gtk-CRITICAL **: IA__gtk_widget_unrealize: assertion `GTK_IS_WIDGET (widget)' failed
(opera:13093): Gtk-CRITICAL **: IA__gtk_widget_is_toplevel: assertion `GTK_IS_WIDGET (widget)' failed
opera [crash logging]: CRASH!!
/usr/lib/opera/opera got signal SIGSEGV at address B6B26E77
Log was created here:
/var/tmp/crash20111110210615.txt
Убито
Для столкнувшихся с этой же проблемой в ArchLinux:
Переехал на
BlogTNG вместо классической связки плагинов blog/tag/discussion. Разработчики, к слову, те же самые.
Уже пришлось малость залезть в исходники, для корректировки работы с тегами, но в целом ощущения положительные.
Теперь будем постепенно адаптировать другие части системы под новый блого-движок.
Как сказал один умный дядька (вот к своему позору запамятовал как его зовут, вроде Аристотель): “Дайте мне библиотеку и я в пустыне построю университет!”. Пусть у меня тут не университет, но… полезных и интересных книг? есть их у меня! Посему начинаю проект по публикации своей домашней электронной библиотеки. И вот первые ласточки:
материалы по учебе в ДВГТУ
Планирую сходить на Туманную в день шуток и приколов. Желающим присоединиться - в комменты.
Подкинули ссылочку на интересную статью в компьютерее, называется
“Пять процентов”
Интересная нужно сказать теория. Тут вот думаю, к каким “пяти процентам” отношусь я?
Вообще жизнь интересная штука: каждый день, новая шуточка, даже интересно, а что ж завтра то будет?
В QLandkarteGT есть удобная вещь - экспорт видимой области карты со всеми отображаемыми точками, треками, измерениями и т.п. в растровый (PNG) файл.
Мне же потребовалось, что бы вся карта как есть была экспортирована. Пришлось полезть в исходники. Прямого пути сделать такое не нашлось, пришлось сделать несколько костыльно (имхо), но работоспособно (ибо нужно срочно - готовить карту к предстоящим соревнованиям).
Патч подкатом.
Сегодня столкнулся с тем, что привязывая карту в QLandkarteGT, получаю такую ошибку:
/usr/bin/gdal_translate -a_srs +proj=merc +a=6378245.0000 +b=6356863.0188 +towgs84=24,-123,-94,-0.02,0.25,0.13,1.1,0 +units=m +no_defs -gcp 108 182 inf inf -gcp 3310 189 inf inf -gcp 3308 3126 inf inf -gcp 93 3119 inf inf -gcp 1704 1657 inf inf /home/hatred/maps/1/src/K-53-26-view-raw.tiff /tmp/qt_temp.B12852
Input file size is 3402, 3428
0...10...20...30...40...50...60...70...80...90...100 - done.
/usr/bin/gdalwarp -order 1 -r cubic -dstnodata "255" /tmp/qt_temp.B12852 /tmp/qt_temp.u12852
ERROR 1: Attempt to create -2147483648x-2147483648 dataset is illegal,sizes must be larger than zero.
Creating output file that is -2147483648P x -2147483648L.
Неудачно!
Сначала было подумал, что поломано в SVN версии, однако, в релизной 1.2.4 ситуация точно такая же.
Сразу и сходу смутили параметры inf в опции -gcp. Так что решил поглядеть в коде, благо собираю из SVN и он у меня всегда под рукой.
Немного времени, расстановка логов, анализ привели к тому что обнаружилось двойное преобразование координат в функции
bool GPS_Math_Str_To_LongLat(const QString& str, float& lon, float& lat, const QString& srcproj, const QString& tarproj)
в файле GeoMath.cpp
Первое преобразование было в блоке кода:
if(GPS_Math_Str_To_Deg(str, lon, lat,true))
{
if(pjTar)
{
u = lon * DEG_TO_RAD;
v = lat * DEG_TO_RAD;
pj_transform(pjSrc,pjTar,1,0,&u,&v,0);
}
}
else
а второе преобразование в следующем блоке кода:
if(pjTar && pjSrc)
{
pj_transform(pjSrc,pjTar,1,0,&u,&v,0);
}
Беглый анализ привёл к мысли, что производился редизайн кода, оптимизация и убирание дублирующихся блоков кода, в результате просто недосмотрели одно место.
Сменил первый блок на такой:
if(GPS_Math_Str_To_Deg(str, lon, lat,true))
{
u = lon * DEG_TO_RAD;
v = lat * DEG_TO_RAD;
}
else
пересобрал и всё заработало отлично и замечательно.
UPD: а теперь всё то же самое, но в виде патча:
Index: src/GeoMath.cpp
===================================================================
--- src/GeoMath.cpp (revision 3010)
@@ -392,12 +392,8 @@
if(GPS_Math_Str_To_Deg(str, lon, lat,true))
{
- if(pjTar)
- {
- u = lon * DEG_TO_RAD;
- v = lat * DEG_TO_RAD;
- pj_transform(pjSrc,pjTar,1,0,&u,&v,0);
- }
+ u = lon * DEG_TO_RAD;
+ v = lat * DEG_TO_RAD;
}
else
{
PS автору письмо отправлено