Jump to content

Tim Chilvers

Members
  • Content Count

    3
  • Joined

  • Last visited

Everything posted by Tim Chilvers

  1. 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
  2. Tim Chilvers

    Returning a dynamic array from DLL

    Hi Remy, Thanks for the help, this works perfectly both as an "internel" plugin and also via a DLL. I had to make a slight change to the VarArrayCreate call as it wanted the parameters to be: VarArrayCreate([0, 1], varUnknown). This maybe different as I am using Delphi 10.4.2
×