Как вы загружаете bpl? Вы оставляете это Delphi для загрузки или вручную загружаете bpl? Если вы загружаете bpl вручную, загружаете ли вы его как «прямую» dll или используете LoadPackage для загрузки его как пакета delphi? Я думаю, что для запуска разделов инициализации, выполняемых vcl, требуется либо позволить vcl загрузить его (посредством обработки по требованию), либо использовать LoadPackage ...

я есть модуль внутри .bpl, и мне нужен список строк для новой функции, которую я написал. Я хочу, чтобы список строк сохранялся на протяжении всего жизненного цикла приложения, чтобы каждый вызов мог основываться на том, что обнаружил предыдущий вызов.

Таким образом, он объявлен глобально в модуле, и я инициализирую его в разделе «Инициализация», например:

var
  ProductLookup : TStrings;  
...

function foo : boolean;
begin
  result := (ProductLookup.IndexOfName('bar') >=0); //blow up here. It's nil. Why?
end;
....

initialization
  ProductLookup := TStringList.Create;  // This should get run, but doesn't.

finalization
  FreeAndNil(ProductLookup);

end.

Когда я его проверил, все было хорошо. Но когда он запускается из основного приложения, я был взорван с нарушением прав доступа, потому что список строк был нулевым. Так что теперь я прибегаю к проверке на nil в функции foo и к созданию при необходимости. Но я в недоумении, почему инициализация не работает для меня. Я помещаю сообщение об отладке прямо в инициализацию, и оно не запускается, когда он загружается как BPL, но запускается, если я компилирую непосредственно в свой dUnit exe. Есть идеи? Delphi2005.

 Darian Miller06 янв. 2011 г., 20:18
Проверьте ответ Роба Кеннеди здесь:groups.google.com/group/...

Ответы на вопрос(4)

ую загружаете bpl? Если вы загружаете bpl вручную, загружаете ли вы его как «прямую» dll или используете LoadPackage для загрузки его как пакета delphi? Я думаю, что для запуска разделов инициализации, выполняемых vcl, требуется либо позволить vcl загрузить его (посредством обработки по требованию), либо использовать LoadPackage ...

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

http://qc.embarcadero.com/wc/qcmain.aspx?d=61968

 Remy Lebeau09 июн. 2017 г., 19:23
Обратите внимание, чтоQualityCentral теперь закрыт, так что вы не можете получить доступqc.embarcadero.com ссылки больше. Если вам нужен доступ к старым данным контроля качества, посмотрите наQCScraper.
 Chris Thornton06 янв. 2011 г., 22:23
Похоже, моя проблема. +1

енных обстоятельствах. Если бы мне пришлось угадывать, я бы сказал, что этот BPL связан с вашей программой во время загрузки и не загружается динамически позже? Попробуйте ввести название используемого вами устройства в программуиспользования список в ДНР. Это должно исправить это.

 Chris Thornton06 янв. 2011 г., 22:22
Сложность заключается в том, что существует около 100 различных EXE-файлов и .BPL, которые используют этот конкретный .BPL, и мне не разрешено их перестраивать. Поэтому разумные подходы не всегда будут работать. Хорошая идея, и +1 за то, что обычно было бы хорошей техникой.
Решение Вопроса

Я отвечал на это раньше:

Если операционная система загружает BPL как часть загрузки соответствующего EXE-файла, будут вызваны не все разделы инициализации. Вместо этого вызываются только разделы из модулей, которые явно используются чем-то другим в программе.

Если код в разделе инициализации регистрирует класс, а затем вы только косвенно ссылаетесь на этот класс, скажем, ища его по имени в списке, то раздел инициализации модуля может не вызываться. Добавление этого модуля к любому условию «использования» в вашей программе должно решить эту проблему.

Чтобы обойти эту проблему, вы можете самостоятельно инициализировать модули пакета, вызвавInitializePackage функция в модуле SysUtils. Требуется дескриптор модуля, который вы можете получить, вызвавGetModuleHandle API-функция. Эта функция будет вызывать только разделы инициализации модулей, которые еще не были инициализированы. Во всяком случае, это мое наблюдение.

Если вы позвонитеInitializePackageтогда вам также следует позвонитьFinalizePackage, Когда ваш пакет будет выгружен, разделы финализации будут вызваны для всех модулей, которые были автоматически инициализированы.

Если ОС делаетне автоматически загрузить ваш пакет, затем вы загружаете его сLoadPackage функция. Он инициализирует все модули пакета для вас, поэтому вам не нужно звонитьInitializePackage себя. Точно так же,UnloadPackage завершит все для вас.

 Chris Thornton06 янв. 2011 г., 22:20
Круто - спасибо.
 Darian Miller06 янв. 2011 г., 20:50
Вы получили мой +1! :)

Ваш ответ на вопрос