Запретить приложению Delphi MDI создавать TApplication во внешней DLL - PullRequest
3 голосов
/ 10 января 2012

Это вопрос (остальное просто, чтобы вы могли сказать мне, что я все делаю неправильно) .

Можно ли каким-то образом убедиться, что первый двоичный файл (т.е. мой исполняемый файл), который будет запущен первым, инициализирует vcl.controls.pas?


Я спросил этот вопрос несколько месяцев назад и я разобрался, как его там исправить и синхронизировать снова заработало просто для Delphi 2009.

Теперь у нас есть Delphi XE2 и наблюдается тот же симптом,TThread.Synchronize блокируется до тех пор, пока система не остановится или вы не наведете указатель мыши на активную форму, в результате чего программа будет работать очень медленно.Я мог воссоздать проблему в Delphi 2009, потому что мне повезло, и я обнаружил, что источником является не связанная со схемой DLL, но я не верю, что это имеет место с XE2.Я не знаю, почему XE2 решает инициализировать код иначе, чем Delphi 7 или 2009, но согласно моему ответу на другой вопрос, ничего не изменилось с TThread, так что это должно быть где-то еще.

Ну, яЯ прошёл инициализацию моего основного MDI-приложения, и он, похоже, вызывает TApplication.Create (что происходит при инициализации VCL.Controls.pas) внутри связанной DLL.Я не могу сказать, что понимаю, почему это проблема, так как я собираю все с одинаковыми пакетами времени выполнения (VCL, RTL и т. Д.).

Ответы [ 2 ]

2 голосов
/ 27 сентября 2012

У нас возникли те же проблемы, которые вы описали (хотя в C ++ Builder). Кажется, есть три возможных решения.

1) Удалите все зависимости VCL из ваших DLL. Это то, к чему в конечном итоге стремится моя компания, но, вероятно, это не очень полезный совет в краткосрочной перспективе.

2) Используйте пакеты вместо DLL. Это официальный ответ, который мы получили от поддержки Borland (давно). По-видимому, если вы создадите пакет (BPL) вместо DLL, он может лучше справиться с выяснением инициализации VCL.

3) Я не знаю, какие скрытые проблемы скрываются с этим третьим решением, потому что это довольно взломано, но вот как я в настоящее время применяю пластырь к нашей системе, пока мы не сможем получить VCL из наших DLL (и это кажется для работы).

WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
    delete Application;
    Application = new TApplication(NULL);

Но я должен признаться, что это заставляет меня немного нервничать (и это заставляет меня чувствовать себя немного грязно).

Идея, которую, как я уверен, вы можете перевести на Паскаль, состоит в том, чтобы уничтожить исходный объект TApplication, созданный DLL и назначенный глобальной переменной Application. Затем создайте свой собственный объект TApplication в исполняемом файле WinMain и назначьте его глобальной переменной Application. Пока ничто не хранит указатель на исходный объект TApplication, прежде чем вы получите возможность его выбросить, похоже, что все должно быть в порядке.

1 голос
/ 13 января 2012

Судя по тому, что вы сказали в комментариях, я понимаю, что здесь происходит ... Если вы используете external для ваших точек входа в DLL из основного exe, они загружаются ОС при запуске программы. Это сильно усложнит ситуацию, поскольку BPL загружаются средой выполнения (используя LoadLibrary()) намного позже этой точки.

Итак, ваша DLL загружает BPL времени выполнения отдельно в EXE, прежде чем EXE успеет выполнить его инициализацию.

...