Перейти к содержанию
Fire Monkey от А до Я

UniSoft

Пользователи
  • Постов

    2
  • Зарегистрирован

  • Посещение

Активность репутации

  1. Like
    UniSoft получил реакцию от Kitty в Проблемы со стилями и релиз конфигурацией XE8 &C++   
    ну исходники библиотек то одни...
    а вот в x64 не проявляется...
    да и еще этот баг там не единственный, понизив приоритет инициализатора все запускается нормально,
    но падает уже при закрытии и в каком-то другом модуле.
     
    патч fmx.lib и cw32mt.lib решают проблему... 
    http://rghost.net/6rNpG5LlC 
    но я бы не рекомендовал это использовать, высока вероятность, 
    что может начать конфликтовать с какими либо другими модулями.
     
    как устроена инициализация, и о каких приоритетах идет речь, 
    можно посмотреть тут: функция _init_exit_proc() 
    C:\Program Files (x86)\Embarcadero\Studio\16.0\source\cpprtl\Source\startup\initexit.c 
    C:\Program Files (x86)\Embarcadero\Studio\16.0\source\cpprtl\rtlinc\_startup.h 
     
    по хорошему, нужно бы отправить баг-репорт, ведь баг то критический,
    но у меня нет EDN аккаунта.
  2. Like
    UniSoft получил реакцию от zairkz в Проблемы со стилями и релиз конфигурацией XE8 &C++   
    Проблема в инициализации модулей, точнее в последовательности их инициализации.   FMX.Types.pas initialization     ...     // <<< тут проблема,      // на момент вызова этого конструктора, инициализация модуля System.Rtti.pas     // еще не выполнялась...     // т.е. модуль System.Rtti.pas инициализируется после FMX.Types.pas     SharedContext := TRttiContext.Create;     ...   System.Rtti.pas class function TRttiContext.Create: TRttiContext; begin   EnsurePoolToken(@Result.FContextToken); end;   constructor TPoolToken.Create; begin   TMonitor.Enter(PoolLock); // вот тут то и падение, модуль еще не инициализирован и PoolLock = nil   try     if Pool = nil then     begin       Pool := TRttiPool.Create;       PoolRefCount := 1;     end     else       Inc(PoolRefCount);   finally     TMonitor.Exit(PoolLock);   end; end;   procedure EnsurePoolToken(TokenRef: PInterface); var   sample: Pointer;     procedure DoCreate;   var     tok: IInterface;   begin     tok := TRttiContext.FGlobalContextToken;     if tok = nil then       tok := TPoolToken.Create;     if AtomicCmpExchange(PPointer(TokenRef)^, Pointer(tok), sample) = sample then     begin       // We won the race to initialize the TokenRef location, so       // zero-out interface reference without decrementing reference count.       PPointer(@tok)^ := nil;     end;   end;   begin   sample := PPointer(TokenRef)^;   if sample <> nil then     Exit;   DoCreate; end;   initialization   ...   PoolLock := TObject.Create;   Есть еще один нюанс, инициализация System.Rtti.pas зачем-то выполняется два раза, к краху это не приведет, но небольшой (не накопительный) memleak будет.   Проблема в библиотеках, и похоже только Win32   ЗЫ. к стилям никакого отношения не имеет... достаточно одной строчки:  void __fastcall TForm1::FormCreate(TObject *Sender) { TValue::From<String>("test"); }
  3. Like
    UniSoft получил реакцию от Kitty в Проблемы со стилями и релиз конфигурацией XE8 &C++   
    Проблема в инициализации модулей, точнее в последовательности их инициализации.   FMX.Types.pas initialization     ...     // <<< тут проблема,      // на момент вызова этого конструктора, инициализация модуля System.Rtti.pas     // еще не выполнялась...     // т.е. модуль System.Rtti.pas инициализируется после FMX.Types.pas     SharedContext := TRttiContext.Create;     ...   System.Rtti.pas class function TRttiContext.Create: TRttiContext; begin   EnsurePoolToken(@Result.FContextToken); end;   constructor TPoolToken.Create; begin   TMonitor.Enter(PoolLock); // вот тут то и падение, модуль еще не инициализирован и PoolLock = nil   try     if Pool = nil then     begin       Pool := TRttiPool.Create;       PoolRefCount := 1;     end     else       Inc(PoolRefCount);   finally     TMonitor.Exit(PoolLock);   end; end;   procedure EnsurePoolToken(TokenRef: PInterface); var   sample: Pointer;     procedure DoCreate;   var     tok: IInterface;   begin     tok := TRttiContext.FGlobalContextToken;     if tok = nil then       tok := TPoolToken.Create;     if AtomicCmpExchange(PPointer(TokenRef)^, Pointer(tok), sample) = sample then     begin       // We won the race to initialize the TokenRef location, so       // zero-out interface reference without decrementing reference count.       PPointer(@tok)^ := nil;     end;   end;   begin   sample := PPointer(TokenRef)^;   if sample <> nil then     Exit;   DoCreate; end;   initialization   ...   PoolLock := TObject.Create;   Есть еще один нюанс, инициализация System.Rtti.pas зачем-то выполняется два раза, к краху это не приведет, но небольшой (не накопительный) memleak будет.   Проблема в библиотеках, и похоже только Win32   ЗЫ. к стилям никакого отношения не имеет... достаточно одной строчки:  void __fastcall TForm1::FormCreate(TObject *Sender) { TValue::From<String>("test"); }
×
×
  • Создать...