Klasy plikach DLL

0

Witam!

Umiem tworzyć własne biblioteki DLL i udostępniać przez nie różne funkcje. Ale w programie potrzebuje czegoś więcej. Ale szczegóły...

Chodzi o to, że w programie mam pewne dane (tekst) i analizator do nich. Analizator analizuje te dane i na ich podstawie wyświetla w ListView odpowiednią strukturę. No i chciałbym ten analizator umieścić w bibliotece DLL. Wiem jak przekazać do niego dane... ale jak uzyskać wynik! Tymbardziej, że wynik to nie liczba, czy napis... tylko - no właśnie. Najlepiej by biblioteka DLL nic nie zwracała tylko generowała drzewo ListView... no ale z poziomu biblioteki DLL nie mam dostępu do klas programu matki. Jak to rozwiązać?

Dla utrudnienia - analizator w bibliotece DLL nie może blokować programu głównego - ma być wykonywany w odrębnym wątku.

Czyli zadanie sprowadza się, jak z biblioteki DLL uzyskać dostęp do klasy z programu matki.

0

To niech wątek tworzy sobie ListView i jako parametr podaje DLL'ce. Funkcja z DLL wypełni go i po zakończeniu wywołania, a wątek przepisze własny ListView do interfejsowego.

0

Czytam kilka razy co napisałeś i nie do końca rozumiem... ale chyba się domyślam.

Chodzi Ci, że w wątku, w bibliotece DLL tworze ListView i wypełniam (to umiem) i na zakończenie przepisuje to do ListView z programu. Ok - ale jak przepisuje?
Przecież albo z biblioteki DLL musiałbym mieć dostęp do ListView z programu głównego, albo z programu głównego dostęp do Listview z biblioteki - a tego właśnie nie wiem jak zrobić. Umiem przekazywać jako parametry napisy, liczby itp. ale nie wiem jak przekazać cały obiekt.

0

Do swojego DLL dodajesz

uses ComCtrls

, w procedurze tworzysz dynamicznie TListView lub TListItems, przypisujesz do nich wartości i wrzucasz jako output do funkcji:

library MakeListView;

{...}

uses ComCtrls;

{...}

function ProcessData({...}): TListView {lub TListItems};
var
  rListView: TListView; {lub rListItems: TListItems}
begin
  {  Tutaj przypisujesz wartości do rListView  }
  Result := rListView;
end;

{...}

exports
  ProcessData as 'ProcessData';
  {...}

end.
0

Prosty przykładzik - bez wątków, ale to w takiej sytuacji łatwo dorobić.

//W pliku DLL dopisz:

uses  ComCtrls;

procedure Procedura(LV:TListView);
begin
with LV.Items.Add do
  begin
  Caption:='Caption';
  SubItems.Add('SubItem');
  end;
end;

exports Procedura;

//W aplikacji głównej dopisz:

type TProc_DLL = procedure (LV:TListView);

var LV:TListView;             //Wydzielony ListView nie zależny od wątku głównego
    DLL:THandle;
    Proc_DLL:TProc_DLL;
begin
LV:=TListView.CreateParented(GetDesktopWindow());
DLL:=LoadLibrary('c:\test.dll');
if (DLL<>0) then
  begin
  Proc_DLL:=GetProcAddress(DLL, 'Procedura');
  if (@Proc_DLL<>nil) then
    begin
    LV.Items.Assign(ListView1.Items);         //Wypełnienie nowego LV wymaga synchronizacji przy wątkach
    Proc_DLL(LV);
    ListView1.Items.Assign(LV.Items);         //Wypełnienie nowym LV wymaga synchronizacji przy wątkach
    end;
  end;
LV.Free;
end;
0

Wypełnienie nowego LV wymaga synchronizacji przy wątkach

Classes.Synchronize: procedure(Method: TThreadMethod);

1 użytkowników online, w tym zalogowanych: 0, gości: 1