Hi,
I am in the process of writting a plugin system for my application and would like to return a dynamic array of interfaces from the plugin DLLs.
The function that is returning the array is below
function TTestWizard.GetCategories(var ArrayCount: Integer): Pointer;
var
LArray: TArray<IProjectItemCategory>;
LManager: IProjectItemCategoryServices;
LCategory: IProjectItemCategory;
begin
SetLength(LArray, 0);
LManager := Services as IProjectItemCategoryServices;
if LManager <> nil then
begin
LCategory := LManager.FindCategory('New');
LArray[0] := LCategory;
ArrayCount := Length(LArray);
Result := LArray[0];
end;
end;
However when I'm trying to run a comparison of the returned interface fields I am getting an AV:
To method that does the work, calls the function, loops through the array and adds the resulting data to a TList<>
procedure TProjectItemDialog.TreeViewFocusChanged(Sender: TBaseVirtualTree;
Node: PVirtualNode; Column: TColumnIndex);
function IsGalleryCategory(const ACategory: IProjectItemCategory;
const AIdString: string): Boolean;
begin
Result := (ACategory <> nil) and (ACategory.IdString = AIdString);
end;
function IsInGalleryCategories(const ACategories: TArray<IProjectItemCategory>;
const AIdString: string): Boolean;
var
LArrayCount: Integer;
begin
Result := False;
if ACategories <> nil then
begin
for LArrayCount := Low(ACategories) to High(ACategories) do
begin
Result := IsGalleryCategory(ACategories[LArrayCount], AIdString);
if Result then
begin
Exit;
end;
end;
end;
end;
var
LData: PCategoryNodeData;
LServices: IWizardServices;
LCount: Integer;
LCategoryCount: Integer;
LWizard: IProjectItemWizard;
LCategory: IProjectItemCategory;
LCategories: TArray<IProjectItemCategory>;
LPtrArrayData: Pointer;
begin
WizardControlList.ItemCount := 0;
try
FWizardList.Clear;
LData := GetNodeData(Node);
if LData <> nil then
begin
LServices := Services as IWizardServices;
if LServices <> nil then
begin
for LCount := 0 to LServices.WizardCount - 1 do
begin
if Supports(LServices.Wizard[LCount], IProjectItemWizard, LWizard) then
begin
LCategory := LWizard.Category;
// LCategories := LWizard.Categories;
LCategoryCount := 0;
LWizard.GetCategories(LPtrArrayData, LCategoryCount);
SetLength(LCategories, LCategoryCount);
Move(LPtrArrayData^, LCategories[0], LCategoryCount);
if IsGalleryCategory(LCategory, LData.Id) or IsInGalleryCategories(LCategories, LData.Id) then
begin
FWizardList.Add(LWizard);
end;
end;
end;
end;
end;
finally
WizardControlList.ItemCount := FWizardList.Count;
end;
end;
The AV is happening in the function IsGalleryCategory when it is being called by IsInGalleryCategories.
If I change to using another function within the DLL to return a TArray<IProjectItemCategory> then everything works correctly. The reason for trying to resurn an array like this is so I can allow people to develop plugins for my application without having to rely on them using Delphi
Tim