Вход/Регистрация
Программирование на Visual C++. Архив рассылки
вернуться

Jenter Алекс

Шрифт:

 RFX_Text(pFX, "Name", m_Name, 50);

 RFX_Date(pFX, "DateOfBirth", m_DateOfBirth);

 pFX->SetFieldType(CFieldExchange::inputParam);

 RFX_Text(pFX, "paramName", m_paramName);

}

:

CPeople Rs(&Db);

Rs.m_paramName = "Alexander";

Rs.Open(CRecordset::snapshot, "{CALL spGetByName(?)}");

О чём ещё полезно знать

В заключительном разделе я рассмотрю несколько не связанных между собою тем, знакомство с которыми может оказаться полезным. 

Транзакции

Транзакция – это блок команд, которые выполняются как единое целое. Другими словами, они либо выполняются все, либо не выполняется ни одна. Транзакция начинается вызовом CDatabase::BeginTrans и завершается вызовом CDatabase::CommitTrans. Все операции по изменению, добавлению и удалению данных вступят в силу только после вызова CommitTrans, причём в любой момент до вызова этой функции транзакцию можно полностью отменить, вызвав функцию CDatabase::Rollback. Используйте CDatabase::CanTransact, чтобы определить, поддерживает ли используемый вами драйвер транзакции.

CRecordset и его потомки

В первой части статьи мы рассмотрели, как использовать CRecordset, порождая от него новые классы. Возникает вопрос: а можно ли использовать этот класс напрямую? Ответ на этот вопрос звучит так: CRecordset может использоваться для доступа к множеству записей, построенному только на основе запроса (а не имени таблицы), и только в режиме read only. Обратиться к значениям конкретных полей в этом случае можно, используя функцию CRecordset::GetFieldValue. Функции CRecordset::Move* используются, как и раньше.

Следующий фрагмент выводит фамилии всех авторов из БД pubs. Так как нам требуется доступ к таблице authors в режиме , мы можем использовать класс CRecordset напрямую.

CRecordset Rs(&Db);

Rs.Open(CRecordset::forwardOnly, "SELECT aau_lname FROM authors");

while (!Rs.IsEOF) {

 CString lname;

 Rs.GetFieldValue((short)0, lname);

 printf ("%s\n", lname);

 Rs.MoveNext;

}

Как обмануть IntelliSense

Мы уже умеем конструировать объекты класса CRecordset, передавая конструктору указатель на соединение: 

CRecordset Rs(&Db);
 

Существует ещё одна эквивалентная форма создания объекта CRecordset: 

CRecordset Rs;

Rs.m_pDatabase = &Db;

Зачем она может понадобиться, спросите вы. Дело в том, что система Microsoft IntelliSense, которая услужливо выдаёт вам списки членов класса и параметров функции прямо, очень болезненно реагирует на конструкторы с параметром: в коде, который следует за вызовом такого конструктора, подсказки попросту перестают появляться. Если вы столкнулись с такой проблемой, смело используйте второй вариант конструирования объекта CRecordset. 

Любые замечания по форме и содержанию статьи вы можете прислать мне по адресу rudankort@mail.ru.

ВОПРОС-ОТВЕТ 

Q. Есть у меня файлы с расширением .pdb (Microsoft C/C++ program database 2.00) (их MS VC++ делает в папке Debug проекта создаются), можно ли с их помощью восстановить исходники программы (размер у них такой, что туда не только прога влезет, но и комментарии к ней в HTML (FrontPage Style) формате :)

Andrey Shtukaturov 

A. Восстановить исходники не удастся, так как их там нет. Зато есть имена классов и глобальных переменных.

Этого вполне достаточно для того чтобы восстановить недокументированный интерфейс COM-объекта.

Дело в том, что согласно реализации COM'а для C++, имена функций членов класса реализующиго интерфейс должны полностью совпадать с именами исходного интерфейса. Плюс свои какие-то матоды. Обычно они не виртуальные так что легко отсекаются.

В .pdb файлах лежат vftable для базовых интерфейсов, так что можно восстановить всю иерархию интерфейсов. И гадать в каком порядке методы в интерфейсе не придется

И собственные методы класса реализующего интерфейс тоже отсекаются.

Для не COM-объектов .pdb файлы тоже могут быть полезны.

Если, например, в перечне экспортируемых из ImgUtil.dll функций содержится скупое "DecodeImage", то в .pdb файле честно написано, что это "_DecodeImage@12", т.е. уже извесно количество параметров. Это для функций описанных как extern "C". Для функций C++ в .pdb файле будет полное задекорированное имя.

Типа "?DecodeImage@@YAJPAVISniffStream@@PAVIMapMIMEToCLSID@@PAVIImageDecodeEventSink@@@Z"

Что после пропускания через утилиту UndName из набора утилит поставляемого MS с PlatformSDK выглядит как "long cdecl DecodeImage(class ISniffStream *, class IMapMIMEToCLSID *, class IImageDecodeEventSink *)".

Более чем достаточно для восстановления не целиком исходников, но хоть декларации функций.

Paul Bludov 
В ПОИСКАХ ИСТИНЫ 

Q. Насколько корректно будут работать методы контроля утечек памяти (в частности объект CMemoryState) в многопоточных приложениях? 

У меня сложилось впечатление, что объект CMemoryState не делает различия в каком потоке вызывались операторы new с момента обращения к memState.Checkpoint до обращения к memState.DumpAllObjectsSince. 

Видимо "моментальные снимки" распределённой памяти в данном случае не информативны, ведь несколько потоков работают в одном адресном пространстве?

Николай Турпитко 
  • Читать дальше
  • 1
  • ...
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: