четверг, 30 сентября 2010 г.
Processor Check for 64-Bit Compatibility v6.0
Version: 6.0 | 5/09/07 | Build 45731
This is a standalone processor check utility which you can use without
VMware Workstation to perform the same check and determine whether
your CPU is supported for virtual machines with 64-bit guest operating
systems.
Note: This utility is provided without support from VMware.
Download for Windows
h..p://download3.vmware.com/software/wkst/VMware-guest64check-6.0.0-45731.exe
h..p://www.megaupload.com/?d=J2SO450M
Download for Linux
h..p://download3.vmware.com/software/wkst/VMware-guest64check-6.0.0-45731
h..p://www.megaupload.com/?d=EMQ2KYBW
Processor Check Guide
h..p://www.vmware.com/pdf/processor_check.pdf
h..p://www.megaupload.com/?d=U0YYTYZF
понедельник, 27 сентября 2010 г.
CreateProcessWithLogon
http://msdn.microsoft.com/en-us/library/aa379608%28v=VS.85%29.aspx
BOOL WINAPI CreateProcessWithLogonW(
__in LPCWSTR lpUsername,
__in_opt LPCWSTR lpDomain,
__in LPCWSTR lpPassword,
__in DWORD dwLogonFlags,
__in_opt LPCWSTR lpApplicationName,
__inout_opt LPWSTR lpCommandLine,
__in DWORD dwCreationFlags,
__in_opt LPVOID lpEnvironment,
__in_opt LPCWSTR lpCurrentDirectory,
__in LPSTARTUPINFOW lpStartupInfo,
__out LPPROCESS_INFORMATION lpProcessInfo
);
try this
do
{
WCHAR _domain [MAX_COMPUTERNAME_LENGTH + 1];
DWORD l = sizeof _domain;
if (!(_Result = GetComputerNameW (_domain, &l))) break;
LPWSTR
_login = argv[1],
_password = argv[2],
_cmdline = argv[3],
_path = argc > 4 ? argv[4] : NULL;
PROCESS_INFORMATION pi;
_STARTUPINFOW si = { sizeof (_STARTUPINFOW) };
_Result = CreateProcessWithLogonW (_login, _domain, _password,
LOGON_WITH_PROFILE, NULL, _cmdline, NULL, NULL, _path, &si, π);
if (!_Result) break;
CloseHandle (pi.hProcess);
CloseHandle (pi.hThread);
}
while (false);
воскресенье, 26 сентября 2010 г.
четверг, 23 сентября 2010 г.
среда, 22 сентября 2010 г.
Сборка Qt без зависимостей (MS Visual Studio)
Часто, при попытке запуска Qt-зависимого приложения на "чистой" системе невозможна из-за отсутствия на ней redistributive paket MS Visual Studio ***. Это тем более становиться неожиданным, когда сам проект компилировался в операционной системе с заведомо установленной студией и никаких проблем не вызывал.
Простое решение - поставить статическую сбоку библиотек в настройке проекта - помогает только для MFC/ATL (не CLR) проектов. Но не для Qt! А всё потому, что изначально, библиотеки Qt:Framework Only для работы в MS Visual Studio содержат зависимости от msvc*.dll.
Задача: убрать зависимость Qt библиотек и приложений, их использующих, от динамических библиотек MS Visual Studio (msvc*.dll).
Все действия проводим до конфигурирования командой configure!
qmake.conf
Для начала изменим файл qmake.conf. Откройте его по адресу
msvc | Visual Studio 6 |
---|---|
msvc.net | Visual Studio.NET 2002-2003 |
msvc2005 | Visual Studio.NET 2005 |
msvc2008 | Visual Studio.NET 2008 |
Потребуется внести следующие изменения:
Заменить
QMAKE_CFLAGS_RELEASE = -O2 -MD
QMAKE_CFLAGS_DEBUG = -Zi -MDd
На
QMAKE_CFLAGS_RELEASE = -O2 -MT
QMAKE_CFLAGS_DEBUG = -Zi -MTd
Этими ключами мы даем понять компилятору, что при сборке Qt необходимо статически прилинковать все необходимые библиотеки компилятора.
Но при попытке откомпилировать Qt, мы получим ошибку от mt.exe. Читаем дальше.
Manifest
Manifest - это файл, в котором, грубо говоря, описываются все зависимости приложения. При использовании статической компиляции библиотек компилятора, Manifest становится ненужным и не генерируется. И при попытке mt.exe присоединить его к проекту и получается ошибка. Чтобы избавится от этой проблемы, необходимо слегка изменить некоторые файлы.
Способ №1
В уже открытом нами файле qmake.conf:
Заменить
CONFIG += qt warn_on release incremental flat link_prl precompile_header autogen_precompile_source copy_dir_files
debug_and_release debug_and_release_target embed_manifest_dll embed_manifest_exe
На
CONFIG += qt warn_on release incremental flat link_prl precompile_header autogen_precompile_source copy_dir_files
debug_and_release debug_and_release_target
Т.е. удалить embed_manifest_dll embed_manifest_exe
Данными изменениями мы в явном виде запрещаем подключения манифестов к проекту.
Способ №2
Зайдем в директорию
Заменить
QMAKE_POST_LINK = $$quote(mt.exe -nologo -manifest \"$$replace(OBJECTS_DIR,/,\\)\\$${NOPATH_TARGET}.intermediate.manifest\"
-outputresource:$(DESTDIR_TARGET);1$$escape_expand(\n\t))
На
QMAKE_POST_LINK = $$quote(@if exist \"$$replace(OBJECTS_DIR,/,\\)\\$${NOPATH_TARGET}.intermediate.manifest\" mt.exe -nologo
-manifest \"$$replace(OBJECTS_DIR,/,\\)\\$${NOPATH_TARGET}.intermediate.manifest\" -outputresource:$(DESTDIR_TARGET);
1$$escape_expand(\n\t))
Тоже самое проделываем для файла embed_manifest_dll.prf
В измененной строке nmake проверит, сгенерирован ли манифест, и только в этом случае добавит его к проекту. Способ является более универсальным, хотя в большинстве случаев принципиальной разницы между ними нет.
Итог
Теперь осталось только запустить configure.exe с необходимыми вам ключами (включая -static), а затем использовать nmake. Все проекты, создаваемые при помощи qmake, уже будут иметь необходимые настройки.
Проверить проделанную работу можно, используя Total Commander. Достаточно только выделить любое приложение, откомпилированое с данной версией Qt, нажать F3 и во вкладке Dll Dependency убедится в отсутствии в списке MSVCR**.dll.
Опыт применения
Проделанные действия для Qt libraries 4.6.3 for Windows (VS 2008, 194 MB) в приложении к MS Visual Studio 2005 не привели к желаемому результату. Зависимость от MSVCR90.dll, которая наблюдается в Qt4.6.3 изменилась на зависимость от MSVCR80.dll. И, что бы в этом убедится, достаточно запустить компиляцию и дождаться появления (обновления) moc.exe в папке BIN. И F3 в Total Commander сразу подскажет стоит ли продолжать компиляцию.
Тем не менее, следующие действия решили проблему:
1. Выполнить замену ключей компилятора MD на MT и MDd на MTd, как описано выше.
2. Дописать в строке для линковщика QMAKE_LFLAGS = /NOLOGO /DELAYLOAD:\"OleAcc.dll\". Честно говоря, необходимость в этом действии сомнительна. Однако, строка параметров линковщика для проекта, созданного в MS Visual Studio 2005, для Shared... и Static... отличаются именно на /DELAYLOAD:\"OleAcc.dll\"
3. К параметрам configure.exe необходимо добавить ключ -no-crt. Без него линковщик спотыкается на MT (MTd) и выдаёт невообразимые ошибки. Это вызвано тем, что, вероятно, где-то в ключах компилятора прячется -clr, который и не даёт сделать статическую сборку.
Примечание. Применение ключа -static не обязательно для данной задачи. Манифесты так же трогать не обязательно.
Для удобства можно применить *.bat файл, следующего содержания:
::все переменные создадутся локально и будут безболезненно убраны
setlocal
::если у вас когда-то был QNX IDE это поможет
set MAKEFLAGS=
::переменные окружения от студии
call "C:\Program Files\Microsoft Visual Studio 8\VC\vcvarsall.bat" x86
::путь куда установилась библиотека
set QTDIR=c:\Qt\4.6.3
set PATH=c:\Qt\4.6.3\bin;%PATH%
::собственно, для чего компилируется
set QMAKESPEC=win32-msvc2005
::перейти в папку с библиотекой
cd %QTDIR%
::на всякий случай %)
nmake confclean
::для ускорения процесса применены -fast -no-qmake
::(повторно компилировать qmake.exe нет необходимости).
configure -debug-and-release -opensource -fast -no-qmake -no-crt
::И без -static всё успешно компирирует
::А вот и причина приводящая к появлению большого количества свободного времени :)
nmake
::Это на случай запуска не из консоли.
pause
::Все переменные окружения безопасно изымаются.
endlocal
Если применялся -static, то в свойствах нового проекта: "Configuration Properties" -> "C/C++" -> "Code Generation" -> параметр "Runtime Library" должен быть выставлен на "Multi-threaded (/MT)".
Сборка Qt без зависимостей (MinGW)
Все действия проводим до конфигурирования командой configure!
Qt 4.3 и выше
Отредактируйте
1. Замените
QMAKE_LFLAGS = -enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc
на (add -static)
QMAKE_LFLAGS = -static -enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc
Qt 4.2 и ниже
Отредактируйте
1. Замените
QMAKE_CFLAGS_THREAD = -mthreads
на (remove -mthreads)
QMAKE_CFLAGS_THREAD =
2. Замените
QMAKE_LFLAGS = -mthreads -Wl,-enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc
на (remove -mthreads, add -static)
QMAKE_LFLAGS = -static -Wl,-enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc
Теперь осталось только запустить configure.exe с необходимыми вам ключами (включая -static), а затем использовать mingw32-make.exe. Все проекты, создаваемые при помощи qmake, уже будут иметь необходимые настройки.
nomake in Qt
-nomake
понедельник, 20 сентября 2010 г.
SQL Server 2008 on Server Core 2008 R2
In this article and video I’ll show you how to install SQL Server 2008 on Server Core 2008 R2.
Watch the video here: http://www.nullsession.com/tv/
Please note that this is UNSUPPORTED as far as I know!
Update: http://msdn.microsoft.com/en-us/library/ms143506.aspx#EEx64 states that it’s not supported and I’ve got this confirmed via email. Your on your own if you put it in production!
Starting off with a domain joined Windows Server 2008 R2 Core we first need to enable the features we need as prerequisites for SQL Server. These are .Net Framework and Powershell. Note that the WOW-components are enabled also. This makes it possible to run 32-bit software on an x64 platform.
The tool we’re using is the “new” image management tool “dism.exe”.
Dism /online /enable-feature /featurename: NetFx2-ServerCore /featurename: ServerCore-WOW64 /featurename:NetFx3-ServerCore-WOW64 /featurename:NetFx2-ServerCore-WOW64 /featurename: NetFx3-ServerCore /featurename:MicrosoftWindowsPowerShell
Once we’ve added the needed features we’re ready to kick off the SQL Server installation. This is done unattended and you don’t have to extract it first, you can like I do in the video run the installation directly from your downloaded package. It’ll self-extract and run correctly anyway. (At least SQL Server 2008 Express Edition did I’ll say.)
(All on one line, paragraphed for clarity)Setup.exe /qs /ACTION=Install /FEATURES=SQL /INSTANCENAME=MSSQLSERVER
/SQLSVCACCOUNT="yourdomain\sqlserviceaccount"
/SQLSVCPASSWORD="sqlserviceaccountpassword"
/SQLSYSADMINACCOUNTS="yourdomain\sqladminusername"
/AGTSVCACCOUNT="NT AUTHORITY\Network Service"
Once it’s done, which takes 5-15 minutes (your mileage may vary!) we’ll need to:
Stop the service: net stop mssqlserver
Fire up the good ‘ol regedit.exe
Navigate to: HKLM\Software\Microsoft\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQLServer\SuperSocketNetLib\TCP
Set Enabled to 1 and exit regedit.exe
Start the service: net start mssqlserver
Once started we have to enable the correct ports in the firewall for remote management to work:
netsh advfirewall firewall [enter]
set rule group=”remote administration” new enable=yes [enter]
add rule name=”Open Port 1433” dir=in action=allow protocol=TCP localport=1433 [enter]
Now we can switch to our graphical box. On this one you’ll have to run the setup and only select the management tools (there’s no how-to on this one since it’s point and click…).
Fire it up and enter the name of your Core-box now running SQL Server!
пятница, 17 сентября 2010 г.
http://www.formortals.com/build-qt-static-small-microsoft-intel-gcc-compiler/
Intel® C++ Compiler for Linux* - Statically linking Intel provided libraries into your application
Published On : | September 18, 2008 9:00 PM PDT |
|
By default, some Intel provided libraries are linked dynamically into your application, such as libcxaguard.so. This may not be desired, if you plan to run your application on a system that does not have the Intel® C++ Compiler installed on it or you do not want to redistribute the Intel provided libraries with your application.
Use one of the following options to resolve this issue:
- Link all libraries statically using the -static option. This may not be desired since non-Intel libraries are also linked statically, which can cause a significant increase in the size of the executable.
OR
- Link the Intel provided libraries using the -static-intel option. For the 9.1 compiler, use the option -i-static. All other libraries are linked using the default behavior (i.e., system libraries are dynamically linked).
--------------
/link specify that all options following '/link' are for the linker
/F
/LD[d] produce a DLL instead of an EXE ('d' = debug version)
/MD[d] use dynamically-loaded, multithread C runtime
/MT[d] use statically-linked, multithread C runtime (DEFAULT with
Microsoft Visual Studio 2005 and later)
/ML[d] use statically-linked, single thread C runtime (only valid in
Microsoft Visual Studio 2003 environment)
/Zl omit library names from object file
среда, 15 сентября 2010 г.
eXaro
Описание:eXaro - это свободный генератор отчетов подобно Jasper или Crystal. eXaro очень просто втраивается в любое приложение написанное с помощью кроссплатформенного тулкита Qt. Имеет встроенный графический дизайнер отчетов, предпросмотр сгенерированных отчетов, поиск по содержимому отчета.Позволяет экспортировать отчеты в несколько различных форматов.
https://docs.google.com/document/pub?id=18-et6uH-p43BOTocaSlLnT5_WdzhHumhNYySRL4CHEM
QT Widgets & Apps
IMPOMEZIA Simple Chat
Версия: 0.7.3Сайт: ссылка...
Лицензия: GPL
Описание: IMPOMEZIA Simple Chat — это простой кроссплатформенный клиент-серверный чат для локальных сетей и Интернета с возможностью индивидуальной настройки под конкретную сеть, с открытыми исходными текстами, написанный на Qt/C++. Разработка была начата 25 марта 2008 года, для нужд небольшой локальной сети Achim Network.
QSpeedTest
Версия: rev16Сайт: ссылка...
Лицензия: GPL
GUI утилита написанная на C++ с использованием Qt для оценки состояния и скорости интернета или диагностики сетевого доступа и одновременной загрузки тестовых файлов из настраиваемых список целевых серверов.
iTest
Версия: 1.4.1Сайт: ссылка...
Лицензия: GPL
iTest - это приложение для тестирования знаний. Оно состоит из двух частей: iTestServer - вопрос/ответ редактор БД и сервер. iTestClient - клиент используемый студентами для проверки знаний.
JulyRegApi - класс для удобной работы с реестром Windows
Версия: 1.2Сайт: ссылка...
Скачать: JulyRegApi.zip
Лицензия: GPL
JulyRegApi - класс для удобного редактирования любых веток реестра Windows на Qt написанный на WinApi JulyRegApi - класс на Qt для удобной работы с реестром Windows Примечания: Все функции являются статическими и можно использовать их не создавая переменных класса. В функцию regWrite можно передавать значения в типах: QByteArray, QString, Int. Тип HKEY_LIST может принимать такие значения в соответствии с веткой реестра: HK_CLASSES_ROOT HK_CURRENT_USER HK_LOCAL_MACHINE HK_USERS HK_CURRENT_CONFIGФункции для получения и записи значений реестра:
QDwm
Версия: 1.0.4.1Сайт: ссылка...
Лицензия: LGPL
QDwm предоставляет классы, которые позволяют приложениям на Qt использовать особенности Windows Aero.
qDBSync
Версия: 0.0.3Сайт: ссылка...
Лицензия: GPL
Утилита для работы с командной строкой, для синхронизации неоднородных баз данных. Работает с Qt драйверами (драйвера для SQLite, QDBC, Firebird включены. Драйвера для IBase, DB2, Postgeress, Mysql в зависимости от того, собрана с ними Qt4 или нет.
SQLite Database Browser
Версия: 2.0b1Сайт: ссылка...
Лицензия: Public Domain
SQLite Database Browser - это open source GUI утилита для создания, проектирования и редактирования файлов баз данных основанных на SQLite. Есть возможность импорта и экспорта в txt, csv и файлы дампов...
oracleqt
Версия: 2009-02-14Сайт: ссылка...
Лицензия: GPL
Описание:
Драйвер для работы с Oracle на Qt, как для Qt 3 так и для Qt 4. В качестве шаблона был взяты драйвера PostgreSQL для Qt 3 и Qt 4, но код по работе с Oracle был написан с нуля. Смотрите веб-страницу проекта для получения более подробной информации.
clienteODBC
Версия: 0.4Сайт: ссылка...
Лицензия: GPL
Зависимость: Qt 4.5
Описание:
clienteODBC является приложением для соединения с базами данных MS SQL Server посредством ODBC. Оно написано на Qt 4.5 Opensource edition.
QGoogleTranslate
Версия: 0.1bСайт: ссылка...
Лицензия: GPL
QGoogleTranslate, программа для удаленной работы с сервисом Google Translate.
Также программа умеет сворачиватся в системный лоток (tray).
SingleApplication
Версия: 1.0 (Qt 4.4.x)Сайт: ссылка...
Лицензия: LGPL
SingleApplication - Компонента обеспечивающая возможность запуска Qt-приложения в единственном экземпляре. Эта компонента, схожая по функционалу с коммерческим солюшеном QtSingleApplication.
ipQalc
Сайт: ссылка...Лицензия:
Описание:
ipQalc это калькулятор IP адресов (и мое первое C++/QT приложение) написанный для помощи школьным друзьям в качестве практических уроков.
NeoUpDownMeter
Сайт: ссылка...Лицензия:
Описание:
Это приложение было разработано для пользователей Neostrada, но если вы имеете динамический ip, оно и для вас тоже. Приложение поддерживает список передач (загрузок\выгрузок) таким образом вы можете контролировать превышение допустимых пределов передачи.
Вы можете запустить приложение двумя способами:
- daemon - с -d параметром
- normal - без каких-то параметров
Вы можете сначала запустить приложение в качестве демона, а затем как обычное, чтобы увидеть текущие значения.
ВЫЖНО:
app depends on ifconfig, if somethings works wrong type in the console:
# ln -s /sbin/ifconfig /bin
Лицензия: GPL
OneClickFTP
Версия: 0.2.1Сайт: http://sourceforge.net/projects/oneclickftp Скачать...
Описание:
OneClickFtp is a FTP-Client written in C++/Qt4, with which you can Upload Files with just a few Clicks (exactly two). To do that you have to configure Profiles with the Server, Username, Password an the desired Files. Like that a whole Homepage can be uploaded easily.
OneClickFTP depends on QCA2: http://delta.affinix.com/download/qca/2.0/
Scythia
Версия: 0.9.3-2Сайт: http://scythia.free.fr/ Скачать...
Описание:
Scythia is a small and unpretentious FTP client. It’s still unstable but already possesses the most common functions. This client use ONLY the Qt library, and doesn’t have other depends.
The code is not very beautiful, but I didn’t have a great experience. Now I try to improve it at most.
QutXR
Версия: 0.7.0 ()Сайт: ссылка...
Лицензия: LGPL
Описание:
QutXR Qt библиотека основанная на XML-RPC client/server. Она проста в использовании и имеет потоковый серверный класс. Также содержит отличные примеры и документацию, которые помогут быстро написать XML-RPC приложения.
Firewall Builder
Версия: 3.0.3 (Qt 4.x)Сайт: ссылка...
Лицензия: GPL
Описание:
Firewall Builder 3.0 вводит поддержку IPv6 для iptables, PF брандмауэров и расширенных списков доступа Cisco IOS. Теперь вы можете создавать как IPv4 и IPv6 политики, так и списки доступа для маршрутизаторов, используя тот же графический интерфейс и базу данных объектов, которые представляют сетевые адреса и службы. В этой версии брандмауэра объект может иметь любое число политик и NAT правил, которые могут быть использованы для ветвящихся правил или для генерации пользовательских iptables или PF, которые могут использовать внешние скрипты.
ZeroNet
Версия: 2.1Сайт: ссылка...
Лицензия: GPL
Описание:
Учет компьютеров, устройств и подсетей в вашей сети. Использует MySQL для хранения данных.
Command Monitor
Версия:Сайт: ссылка...
Лицензия:
Версия: 0.1 (Qt 4.x)
Сайт: Здесь
Скачать...
Описание:
"Command Monitor" это инструмент, который позволяет периодически выполнять команду и посмотреть результат ее работы. Например, если вы хотите сканировать беспроводную сеть с использованием "iwlist eth1 scan", вы должны повторять команду каждый раз, чтобы видеть есть ли новое. Эта программа делает это для Вас.
"Command Monitor" также позволяет выполнить команды на удаленном компьютере, используя SSH соединение. Теперь вы можете спокойно смотреть количество дочерних процессов Apache на вашем сервере.
Прочтите файл INSTALL, в дистрибутиве, относительно инструкций по установке.
Требует, libssh из Aris Adamantiadis для работы SSH.
Лицензия: GPL
вторник, 14 сентября 2010 г.
Русский язык в Qt приложениях
Posted by druss at 21 Ноябрь , 2009
Столкнулся я с проблемой кодировки русских символов в Qt приложениях под linux(под винду еще не проверял). В Qt Creator все нормально отображается, файл сохранен в utf-8, но при запуске приложения я видел какозабли. Пробовал перекодировать сам исходник, не помогало. И вот потом я наткнулся на вот эту статью и нашел решение проблемы.
Нужно подключить заголовочный файл QTextCodec и использовать вызов статического метода setCodecForTr() или setCodecForCStrings() класса QTextCodec.
Первый метод применяется в случае использования метода tr() для интернациональных приложений, а второй для строк типа CString. Вот небольшой пример:
#include
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("utf-8"));
MainWindow w;
w.setWindowFlags(Qt::Window | Qt::WindowSystemMenuHint);
w.setWindowTitle("Тест");
w.resize(600, 100);
w.show();
return a.exec();
}
cpp tips&trics
Using __FILE__ and __LINE__ to Report Errors
by Curtis Krauskopf
Q: How can I create a string that contains the C++ filename and line number that a runtime error occurs on?
A: The __FILE__ C++ preprocessor directive contains the name of the file being compiled. Similarly, the __LINE__ preprocessor directive contains the line number of the original source file that is being compiled. Both the __FILE__ and __LINE__ preprocessor directives have two underscores both before and after the word. Separating each character of the __FILE__ preprocessor directive looks like:
_ _ F I L E _ _
Listing 1 is a console-mode application that shows an easy way to associate runtime errors with the original source line.
| |
Listing 1: Show the Location of a Runtime Error |
Figure 1 shows the result of running the program in Listing 1:
| |||||||||
Figure 1: The Output of Listing 1 |
Taking It One Step Further
I want every error report to go through a common error() function so that I can set breakpoints when certain errors occur and so I can segregate how errors are handled. For example, I might want some errors to appear on the screen and other errors to be logged to a file. And some errors might need to appear on the screen and be logged to a file.
A prototype for such an error logging function is:
void error(const char *file, const unsigned long line,
const char *msg);
and it would be called like this:
error(__FILE__, __LINE__, "my error message");
Preprocessor Magic
There are three awkward parts to the above solution:
- The __FILE__ and __LINE__ preprocessor directives need to be added to every error() function call.
- It's easy to forget to put both underscores on both parts of the __FILE__ and __LINE__ directives. Getting it wrong will lead to a compile-time error.
- __LINE__ is an integer. Doing string manipulation on an integer just adds another level of complexity to any error() function I create. I will never need to use __LINE__ as an integer -- I always want to use it as a string so that it can be output to the screen or a log file.
It would be nicer if __FILE__ and __LINE__ could somehow be handled automatically so I couldn't get them wrong every time I write an error() call.
What I would like to be able to do is write something like:
error(AT, "my error message");
In the above example, the AT macro would expand to be "c:\temp\test.cpp:5".
The prototype for my new error() function becomes:
void error(const char *location, const char *msg);
Because the Borland C++ Builder compiler automatically merges adjacent strings, I can create a #define for AT that looks like this:
#define AT __FILE__ ":" __LINE__
That doesn't work, though, because __LINE__ expands to an integer. The above #define expands to this at compile-time:
"c:\temp\test.cpp" ":" 5
That is an invalid string because strings can't have an unquoted integer at the end of the string.
A special preprocessor directive that turns a symbol into a string is the # token. Changing the above #define to
#define AT __FILE__ ":" #__LINE__
seems like it should work but it doesn't because the compiler complains that # is an illegal character. The problem is that the # preprocessor symbol is only recognized when it's used like this:
#define symbol(X) #X
So, not being one to fight the problem, I'll change my AT macro to look like this:
#define STRINGIFY(x) #x
#define AT __FILE__ ":" STRINGIFY(__LINE__)
That compiles, but at runtime it yields the bizarre message in Figure 2:
| |||||||||
Figure 2: The preprocessor directive appears in the output. |
As shown in Figure 2, the __LINE__ preprocessor directive itself has become a part of the output!
The solution is to take the STRINGIFY() solution one step further -- to wrap the STRINGIFY() macro in yet another macro:
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define AT __FILE__ ":" TOSTRING(__LINE__)
Listing 2 shows the final sample program and Figure 3 shows the output of Listing 2.
| |
Listing 2: The final solution that turns __LINE__ into a string |
| |||||||||
Figure 3: The Output of Listing 2 |
Visual Studio Support
Tim Johnston tried this solution in Microsoft Video Studio but he found that the __LINE__ preprocessor symbol did not have the correct value in debug mode. His solution was to change the "Debug Information Format" setting on the C/C++ project setting tab. The setting that does not work is "Program Database for Edit and Continue"; the setting that works is "Program Database".
Conclusion:
The preprocessor directives __FILE__ and __LINE__ can provide some useful debugging information. This information can be made available at runtime by print()ing those values to the screen or to a log file.
Transforming the __LINE__ preprocessor directive into a string turned out to be much more difficult than originally imagined. Through the use of some #define preprocessor magic, though, the __LINE__ preprocessor directive was tamed and forced to compile as a string.
This has the advantage that the string is automatically merged with the __FILE__ preprocessor value which creates one string for error processing. This also has the advantage of removing the need for integer to string conversion in the error() function.