Dawno tutaj nie zaglądałem...
Po pierwsze
Napisałeś:
Troszkę chaosu w tym pytaniu, po pierwsze skąd wziął się ten StringGrid, z DLL aplikacji, co dokładnei chcesz w nim umieścić jak wygląda wywołanie DLLa(najlepiej kod).
Chodziło mi o rozdzielenie modułów obliczeniowych (które umieściłem w bibliotece DLL) od aplikacji, która chce z nimi coś robić. W związku z tym DLL-ka eksportuje tylko jedną funkcję służącą do tworzenia obiektów i zwraca interfejs na obiekt, który stworzyła. Jej wywołanie wygląda następująco:
function CreateMyObject(ObjType: TObjectType): IMyObject; stdcall;
TObjectType jest typem obiektu, który chcę stworzyć, a IMyObject interfejsem na klasę bazową dla wszystkich obiektów w DLL-ce.
Po dołączeniu tej biblioteki do aplikacji mogę tworzyć obiekty w dll-ce np. tak:
...
var
ob1: IObject1;
...
begin
ob1 := CreateMyObject(Obiekt1) as IObject1;
...
, gdzie IObject1 jest interfejsem dziedziczącym z IMyObject
Skoro mam obiekt i mam jego interfejs to mogę wywoływać metody, które on implementuje np.:
...
ob1.DoSomething;
...
Ponieważ zawartością tych obiektów są dane, które najłatwiej wyświetlić w formie tablicy ze stringami, czyli najlepiej w obiekcie typu TStringGrid, dlatego też jedną z metod interfejsu bazowego (IMyObject)jest następująca metoda:
procedure View(sg: TStringGrid); stdcall;
Dzięki niej obiekt może się sam wyświetlić w kontrolce TStringGrid.
W związku z tym w aplikacji (MDI) jest okno zawierające taki komponent o nazwie np. sg1. Okno to jest tworzone za każdym razem, kiedy użytkownik chce zobaczyć zawartość danego obiektu. Wówczas w odpowiednim miejscu programu następuje wywołanie tejże funkcji w następujący sposób:
...
ob1.View(sg1);
...
, gdzie ob1 jest wcześniej wspomnianym interfejsem, a sg1 komponentem typu TStringGrid właśnie stworzonym w aplikacji, a nie w DLL-ce.
Ponieważ napisałeś:
Raczej nie przekazuje się rzeczy w ten sposób sg:TStringGrid dużo lepszym pomysłem jest psg:pointer, wówczas psg:=@SG. Przesyłasz adres twojego stringgriga a po drugiej stronie piszesz
var sg:TStringGrid;
sg:=TStringGrid(psg^);
masz przekazanie obiektu po adresie i przywiązanie do niego po 2 stronie.
Takie wywołanie jakiego użyłem, z tego co wiem nie powoduje przekazania obiektu do dll-ki (bo sg1 jest referencją na istniejący gdzieś w pamięci obiekt typu TStringGrid), tylko przekazanie adresu tego obiektu.
W związku z tym nie widzę sensu tego co napisałeś, a mianowicie konieczności konwertowania jeszcze tej referencji na wskaźnik, a potem odwrotnie, tj. wskaźnika na referencję. No i oczywiście nie muszę niczego rzutować, co przy programowaniu obiektowym nie uważam za dobry pomysł i staram się unikać, gdzie się tylko da.
Napisałeś też:
Optymalnie jeśli masz w apliakcji swojego sg a przekazujesz do DLLa jego adres, tam go wypelniasz (ale wypelniasz od razu wlasciwego tego powolanego w aplikacji), nawet zwracaniem nie muszisz sie martwic, bo nie ma czego - wszystko juz jest bo DLL mając adress działał od razu na właściwym SG. Zamykasz DLLa odswieżasz okno (albo robi się to automatycznie) i masz co chciałeś (chyba).
Efekt działania tego co zrobiłem jest dokładnie taki jak napisałeś. Tylko bez konieczności rzutowania wskaźników.
Po drugie
Napisałeś:
Stringi też przekazuje się najlepiej w formie pchar-ów, nie ma sensu kopiować i przesyłać obiektów w tę i z powrotem skoro można przekazaćadres do obiektu.
Jeśli przeczytałeś to co wcześniej napisałem to zapewne zauważyłeś, że nigdzie nie przekazuję żadnych obiektów, tylko referencje na nie (czyli adresy) bądź też interfejsy.
Poza tym nie wyobrażam sobie sensowniejszego zapisu wewnątrz procedury znajdującej się w Dll-ce typu:
procedure View(sg: TStringGrid); stdcall;
niż
sg.Cells[0,0] := 'tekst';
Mam nadzieję, że nikogo nie zanudziłem tym wywodem :)