Я разрабатываю это приложение Delhi 2009 с базой данных SQLite версии 3.7.9, доступ к которой осуществляется компонентами Zeos.Началось с ОК - я могу создать БД, если ее нет, создавать таблицы и вставлять записи - «нормальный материал».Есть небольшая таблица, в которой содержатся последовательные параметры для соединения с некоторым старым оборудованием, и обработчик последовательных коммуникаций должен быть информирован об изменениях параметров соединения, но компоненты Zeos не поддерживают события на SQLite.
Я смотрел наSQLite API и есть «обратный вызов уведомления об изменении данных», поэтому я решил сделать это.Прототип установки:
void *sqlite3_update_hook(
sqlite3*,
void(*)(void *,int ,char const *,char const *,sqlite3_int64),
void*
);
Итак, в Delphi я импортировал вызов DLL:
function sqlite3_update_hook(pDB:pointer;pCallback:pointer;aux:pointer): pointer; stdcall;
..
function sqlite3_update_hook; external 'sqlite3.dll' name 'sqlite3_update_hook';
.. и объявил пустой обратный вызов для тестирования:
function DBcallback(aux:pointer;CBtype:integer;CBdatabaseName:PChar;CBtableName:PChar;CBrowID:Int64):pointer; stdcall;
begin
end;
.. и вызвал установку:
sqlite3_update_hook(SQLiteHandle,@DBcallback,dmOilmon);
SQLiteHandle
- это указатель sqlite3*
для базы данных, полученной из драйвера после подключения.dmOilmon
является экземпляром DataModule, так что при правильной работе я могу вызывать некоторый метод из обратного вызова (да, я знаю, что обратный вызов находится в неизвестном потоке - я могу справиться с этим, я просто буду сигнализировать семафоры).
Хорошая новость: когда я запустил приложение, DBcallback
вызывался, как правило, успешно, при первой вставке.Плохая новость: некоторое время спустя приложение взорвалось «Слишком много исключений» и, как правило, окном процессора было полно «??» (случайной альтернативой была смерть системы и перезагрузка - Vista Ultimate 64).Прерывание в обратном вызове, aux, CBtype
и CBrowID
были все как ожидалось, но подсказка отладчика показала, что CBdatabaseName
/ CBtableName
PChars
указывает на строку китайских символов ..
Я попытался отследить, откуда вызывается обратный вызов - цепочка вызовов проходит по коду драйвера Zeos, по некоторым причинам.Прорвавшись туда и пройдя, я проверил указатель стека, и он одинаков до и после обратного вызова.
Итак, я установил «пустой» обратный вызов, обратный вызов вызывается в ожидаемой точке, но с купеиз хитроумных параметров обратный вызов возвращается туда, откуда он пришел с правильным SP.Кажется, я все сделал правильно, но ...: ((
Кто-нибудь видел это, (или даже исправил это :))?
Можете ли вы предложить механизм, с помощью которого можно успешно осуществить обратный вызов?Можно ли заставить приложение позднее генерировать рекурсивные исключения?
У кого-нибудь есть предложения по дальнейшей отладке?
Rgds, Martin