Delphi TThread. CurrentThread и EAccessViolation - являются этим ошибка или моя некомпетентность..?

Вы можете использовать Форматирование пользовательских типов , чтобы помочь с динамическими запросами:

const valueOrNull = (col, value) => ({
    rawType: true,
    toPostgres: () => {
        if(value === null) {
             return pgp.as.format('$1:name IS NULL', col);
        }
        return pgp.as.format('$1:name = $2', [col, value]);
    }
});

Затем вы можете передать его в качестве значения форматирования:

db.oneOrNone(`SELECT * FROM blah WHERE $/c/`, { c: valueOrNull('col', 123) })

11
задан gabr 7 September 2009 в 13:01
поделиться

4 ответа

К сожалению, это походит на ошибку, связанную с порядком вызова раздела завершения в единице Классов:

DoneThreadSynchronization очищается ThreadLock структура, затем
FreeExternalThreads хочет уничтожить объект Потока, который что Вы просто создали при вызове CurrentThread, и
это требует, чтобы ThreadLock был уже инициализирован в вызове к
EnterCriticalSection(ThreadLock) в TThread.RemoveQueuedEvents...

ОБНОВЛЕНИЕ:
В отчете королевского адвоката существует теперь патч обходного решения.

15
ответ дан 3 December 2019 в 02:31
поделиться

Пока CodeGear не выпускает фиксацию, можно использовать патч ниже. Сохраните его в автономную единицу и используйте его где угодно в Вашей программе. Я попытаюсь добавить его к королевскому адвокату, также.

Эта версия работы с (исходным) D2009, обновите 1 и обновите 2.

{ Fix Delphi 2009's invalid finalization order in Classes.pas.
  Written by Primoz Gabrijelcic, http://gp.17slon.com.
  No rights reserved - released to public domain.
}
unit FixD2009Classes;

interface

implementation

uses
  Windows,
  SysUtils,
  Classes;

type
  TCode = array [0..109] of byte;

{$WARN SYMBOL_PLATFORM OFF}

procedure PatchClasses;
{$IFDEF ConditionalExpressions}
{$IF RTLVersion = 20}
var
  i         : integer;
  oldProtect: cardinal;
  pCode     : ^TCode;
  tmp       : DWORD;
const
  COffsets_Call: array [1..12] of integer = (0, 15, 24, 34, 49, 59, 69, 79, 89, 94, 99, 109);
  COffset_UnRegisterModuleClasses = 106;
  COffset_DoneThreadSynchronization = 94;
  COffset_FreeExternalThreads = 99;
  CCallDelta = COffset_FreeExternalThreads - COffset_DoneThreadSynchronization;
{$IFEND}
{$ENDIF}
begin
{$IFDEF ConditionalExpressions}
{$IF RTLVersion = 20}
  pCode := pointer(cardinal(@TStreamReader.ReadToEnd) + COffset_UnRegisterModuleClasses);
  Win32Check(VirtualProtect(pCode, COffsets_Call[High(COffsets_Call)], PAGE_READWRITE, oldProtect));
  try
    for i := Low(COffsets_Call) to High(COffsets_Call) do
      if pCode^[COffsets_Call[i]] <> $E8 then
        raise Exception.Create('Unexpected version of Classes - cannot patch');
    tmp := PDword(@pCode^[COffset_DoneThreadSynchronization+1])^;
    PDword(@pCode^[COffset_DoneThreadSynchronization+1])^ :=
      PDword(@pCode^[COffset_FreeExternalThreads+1])^ + CCallDelta;
    PDword(@pCode^[COffset_FreeExternalThreads+1])^ := tmp - CCallDelta;
  finally VirtualProtect(pCode, COffsets_Call[High(COffsets_Call)], oldProtect, oldProtect); end;
{$IFEND}
{$ENDIF}
end;

initialization
  PatchClasses;
end.
12
ответ дан 3 December 2019 в 02:31
поделиться

Я думаю, что CurrentThread добавляется в 2009 (или 2007). У меня есть 2006 дома. Но действительно ли Вы уверены, что это - свойство класса?

0
ответ дан 3 December 2019 в 02:31
поделиться

Патч-модуль для Delphi 2009 Update 3.

{ Fix Delphi 2009's invalid finalization order in Classes.pas.
  Written by Primoz Gabrijelcic, http://gp.17slon.com.
  No rights reserved - released to public domain.

  D2009 update 3 only.
}
unit FixD2009Classes;

interface

implementation

uses
  Windows,
  SysUtils,
  Classes;

type
  TCode = array [0..144] of byte;

{$WARN SYMBOL_PLATFORM OFF}

procedure PatchClasses;
{$IFDEF ConditionalExpressions}
{$IF RTLVersion = 20}
var
  i         : integer;
  oldProtect: cardinal;
  pCode     : ^TCode;
  tmp       : DWORD;
const
  COffsets_Call: array [1..12] of integer = (0, 15, 24, 42, 47, 58, 73, 91, 101, 111, 134, 139);
  COffset_UnRegisterModuleClasses = 107;
  COffset_DoneThreadSynchronization = 134;
  COffset_FreeExternalThreads = 139;
  CCallDelta = COffset_FreeExternalThreads - COffset_DoneThreadSynchronization;
{$IFEND}
{$ENDIF}
begin
{$IFDEF ConditionalExpressions}
{$IF RTLVersion = 20}
  pCode := pointer(cardinal(@TStreamReader.ReadToEnd) + COffset_UnRegisterModuleClasses);
  Win32Check(VirtualProtect(pCode, COffsets_Call[High(COffsets_Call)], PAGE_READWRITE, oldProtect));
  try
    for i := Low(COffsets_Call) to High(COffsets_Call) do
      if pCode^[COffsets_Call[i]] <> $E8 then
        raise Exception.Create('Unexpected version of Classes - cannot patch');
    tmp := PDword(@pCode^[COffset_DoneThreadSynchronization+1])^;
    PDword(@pCode^[COffset_DoneThreadSynchronization+1])^ :=
      PDword(@pCode^[COffset_FreeExternalThreads+1])^ + CCallDelta;
    PDword(@pCode^[COffset_FreeExternalThreads+1])^ := tmp - CCallDelta;
  finally VirtualProtect(pCode, COffsets_Call[High(COffsets_Call)], oldProtect, oldProtect); end;
{$IFEND}
{$ENDIF}
end;

initialization
  PatchClasses;
end.
5
ответ дан 3 December 2019 в 02:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: