Я пишу пакет Delphi с помощью RAD Studio XE7. Недавно я столкнулся со странным нарушением доступа, и я не могу понять, почему это произошло. Контекст заключался в том, что я пытался вести список имен шрифтов. Итак, я объявил следующий тип:
ICustomFontList = TList<UnicodeString>;
Внутри одного из моих классов я объявил переменную следующим образом:
m_pCustomFontList: ICustomFontList;
Затем в конструкторе я попытался создать экземпляр этой переменной следующим образом:
m_pCustomFontList := ICustomFontList.Create;
Я скомпилировал пакет и создал проект C++, в котором использовался этот код. Однако я получал странное нарушение прав доступа каждый раз, когда m_pCustomFontList создавался в конструкторе, в строке Begin следующего кода (находится внутри System.Generics.Collections.pas):
constructor TList<T>.Create;
begin
Create(TComparer<T>.Default);
end;
Позже я обнаружил, что TStringList лучше подходит для моих значений, и перешел на этот тип. С этого момента вышеупомянутое нарушение прав доступа больше не появлялось. Однако я не могу понять, в чем проблема. Я создаю несколько TList (или производных от TObjectList) в своих пакетах, и я никогда не сталкивался с такой проблемой ни с каким другим типом TList, который я объявил (т. е. отличным от TList из UnicodeString). Так может ли кто-нибудь объяснить мне, почему этот конкретный TList вызвал нарушение прав доступа при построении? Теоретически ничто не мешает создать TList из UnicodeString, если это мое желание, или я ошибаюсь?
С уважением
--- РЕДАКТИРОВАТЬ от 15.02.2017
Вот небольшой пример, который воспроизводит проблему на моем компьютере. Для этого должен быть создан пакетный проект в Delphi, а C++ VCL формирует проект приложения, которое будет использовать этот пакет. В пакете создайте новый блок и скопируйте следующий код:
unit Unit1;
interface
uses System.Generics.Collections;
type
ICustomFontList = TList<UnicodeString>;
TaClass = class
private
m_pCustomFontList: ICustomFontList;
public
constructor Create; virtual;
end;
implementation
constructor TaClass.Create;
begin
inherited Create;
m_pCustomFontList := ICustomFontList.Create;
end;
end.
В проекте c++ просто добавьте эту строку в конструктор TForm1:
std::auto_ptr<TaClass> paClass(new TaClass());
затем соберите пакет и запустите проект
С уважением
TStringList
не обязательно лучше. Он несет гораздо больше багажа. Изменится ли что-то, если вы будете использоватьTList<UnicodeString>
илиTList<string>
вместо своего псевдонима? - person David Heffernan   schedule 14.02.2017ICustomFontList
в пакете иICustomFontList
в exe — это разные классы. Вы можете убедиться в этом, сравнивm_pCustomFontList.ClassType
иICustomFontList
внутри и снаружи упаковки. Может быть, это корень проблемы. Это поведение можно исправить, объявив другой класс, напримерICustomFontList = class(TList<UnicodeString>)
. - person Michael Izvekov   schedule 15.02.2017