Jak z DLLa wywołać procedure i...

0

Mam taki problem. Napisałem program (nazwijmy go głównym), który podłącza dynamicznie moją bibliotekę DLL i wywołuje z niej formularz (okno konfiguracyjne), wszystko ładnie działa i teraz pojawia się problem jak z tego formularza z DLLa wywołać funkcję lub procedurę w głownej aplikaji np: w celu odświeżenia zmiany konfiguracji, przesłanie zmienionych danych funkcją z parametrami. Czy może dałoby się zaimportować funkcje do DLLa z głównej aplikacji?

Próbowałem w aplik. głównej wyeksportować funkcje do DLLa, w DLLu przypisałem aplikację exe jako bilbiotekę statyczną, niby działa, ale po chwili wszystko się wykrzacza...

Jak to zrobić żeby działało? Z góry dziękuję za odpowiedź.
MacGyver

0

Jeśli już to musisz kombinować z podanei madresu funkcji i podmienieniem w DLLu - dośc skomplikowana sprawa:)
Pytanie czemu robisz wszystko aby sobie utrudnić życie.
Zacznijmy tak, masz DLL który coś tam robi w oparciu o konfigurację z programu głównego, ta konfiguracja może się zmieniać.
W DLLu robisz strukturę która odwzorowuje co jest ci potrzebne z konfiguracji. Nasteponei robisz funkcję która może tą konfiguracjęzmeiniać, po trzecie robisz swoją procedurę która ma pracować i reagować na zmianę konfiguracji, ale tym razem korzysta ona z DLLowej kopii.
Uruchamiasz apliakcję główną, wysyłasz ustawienia konfiguracji do DLLa (warto by domyślne miały sens jakbyś zapomniał o ustawieniu na początku programu), a następnei wywołujesz swoją długo pracującą procedurę z DLLa. Jeśli chcesz zmienić/ustawić konfigurację uruchamiasz procedurę zmiany konfiguracji w DLL, a DLL sam sobie odnajdzie w strukturach DLLa. Prostsze, bez zbędnych kombonacji, wymaga tylko zrobienia synchronizacji na DLLowej kopii ustawień (choć w takim przypadku powinno chodzić i bez tego, bo 1 procedura zapisuje, a druga czyta, ryzyko tylko w wypadku gdy zmiany muszą być zauważone w całości a nie po kawałku gdyż istnieje ryzyko że np procedura odczyta połowe starych, a polowe nowych ustawien - to ryzyko można łatwo wykluczyćzakładając pseudo sekcję krytyczną, lub inne takie)

0

daban nie szerz defektyzmu

poszukaj, było niedawno i odpowiadałem na to. Nazywa się to funkcja zwrotna

//edit
znalazłem: http://4programmers.net/Forum/262421#262421

0

Taki już jestem, z funkcjami zwrotnymi miałem kiedyś ogromne problemy jak przypisywałem im np. wrzucanie do memo na zakładkach na formie. Okazywało się że jak zakładka była "aktywna" przy starcie programu to nie ma problemu, a jak nie - choć istniała to przy wyłączaniu komputera wyrzucało dziwne komunikaty. Prawdopodobnie coś z obsługą obiektów w delhi. Generalnie teraz unikam powiązań zakładek z DLLami. Uważam że problem gościa można lepiej rozwiązać, a "funkcje zwrotne" używam tylko do komunikowania o błędach i przesyłaniu komunikatów o stanie procesu. Wydaje mi sięzę lepiej dobrze oprogramować DLLa- podobnie jak klasę, tak aby stany w nim zmieniać odpowiednimi procedurami. Łatwiejsze w użyciu, trudniej się pomylić, łatwiej wykrywać ew. błędy :)

0

Daban: To jest herezja jakaś... Robiłeś kiedyś jakiś system pluginów do trochę bardziej rozbudowanego programu? Tam nie wystarczą takie bajery jak ustawianie jakichś głupich stanów. Plugin musi mieć dostęp do procedur i funkcji w głównym programie, a nawet (chociaż może pośrednio) do funkcji i procedur w pozostąłych wtyczkach załadowanych z głównego programu. Mam z tym trochę doświadczenia i wiem jak to wygląda. Szczególnie wtedy, gdy pisze się coś w WinApi. Oczywistym faktem jest, że na początku zdarzają się błędy w stylu Access Violation, szczególnie gdy się VCL'kami rzuca nie zdajac sobie sprawy z tego, jak są skonstruowane, ale da się to wszystko ładnie i porządnie obejść. Jak wyjdzie PMP3 1.5, to będzie tego przykład :P

0

Herezje? Hmm zależy jak do tego podejść. Nie robiłem żadnych pluginów ani innych dziwnych (dla mnie) rzeczy. Generalnie zajmuję się bazodanówkę, ew. obsługą urządzeń zewnętrznych poprzez standardowe porty. Gdyby nie istniały potrzeby wywoływania procedur z programu w dllu to bym ich nie używał. Nie zmeinia to mojego zdania, że jest to rzecz - podobnie jak wątki które nalezy używać z umiarem i tylko wtedy gdy jest taka potrzeba. Jeśli ktoś tego używa ze zrozumieniem to ma to sens, lecz aby dojść do tego poziomu trzeba się trochę znać i umieć nad tym zapanować. Generalnie zasada nie jest trudna wystarczy podmienić adres procedury i hula:) trochę trudniej z wykonaniem. Miałem problemy i nie pojawiał mi się zaden access viloation, a działało pięknie i ładnie i tylko podczas zamykania pojawiał się dziwny komunikacik coś tam 1400. generalnei mogłem go schwoać i nikt by nie wiedział że coś takiego było, ale straciłem kilka dni aż ustaliłem co z czym się gryzie i wyeliminowałem. Problem się pojawiał gdy używałem zakładek, coby ładnie było - jestem w 90% pewien że wina leży po stronie komponentu - coś z zwalnianiem przechowywanych obiektów na zakładkach było nie tak, błędy nie występowały gdy podmieniane procedury odwoływały się do aktywnej w chwili startu zakładki (nawet jeśli wyświetlana po uruchomieniu była inna), a pojawiały się w przeciwnym przypadku. Poza tym pojawiały się w fazie destroy całości, chociaż już nic nie było wpisywane do jakiegokolwiek komponentu. Od nieznana fluktuacja. We wszystkich programach bez zakładek taka sama konstrukcja działa pierwszorzędnie.
A wracając do tematu, jeśli coś jest wystarczająco skomplikowane by zaistniała potrzeba użycia takich czy innych metod programistycznych jestem za. Nadal jednak twierdzę, że jeśli mozna coś zrobić prostszymi metodami to czemu nie?
Na forum często są pytania o rzeczy które są bardzo trudne, a jak przychodzi co do czego to można coś zrobić w kilku linijkach, tylko trzeba wiedzieć co się chce osiągnąć i potrafić jasno mysleć. Z armatą na muchę?
Dodatkowo jeśli pytającemu zależy na takeij skomplikowanej metodzie i wie p oco mu to, to napisze że potzrebuje i powie dlaczego i wszyscy będą wiedzieli o co chodzi.
Moja metoda jest dobra gdy a - chce się szybko coś w mairę prostego zrobić, b- tworzy się samemu jakiś obiekt, model czegoś i zamyka to w DLLu. Zrobiłem tak np. programowy symulator GPS komunikujący się po RS i ładnie działa. "GPS" siedzi w biblioece a nie głównym programie i program tak naprawde komunikuje się z DLLem i wyświetla co mu DLL zwraca. Gdyby zaszła potrzeba jakiejkolwiek zmiany wyświetlania czy czegokolwiek po prostu biore DLLa i buduję od nowa na nim aplikacje, wszystko co wazne jest w nim. Jeśli jednak nie można z różnych powodów do tego tak podejść to trzeba robić jak mówicie. Ma to jednak pewną wadę, biblioteka i program są mocno powiązane, a np. zmiana procedury w głównym programie najczęściej wymaga zmiany DLLa.

0
MacGyver77 napisał(a)

Jak to zrobić żeby działało? Z góry dziękuję za odpowiedź.
MacGyver

Widzialem w sieci ladnie zrobiony system wtyczek na interfejsach. Niestety nie moge znalezc linka, ale mam przykladowy kod, jak chcesz - moge Ci podeslac.

0

Właśnie cała idea polega na tym, by to było możliwie niezależne. Ale nie znaczy to, że nie powiązane. Ja to robię tak, że jest wiecznie "wstecznie kompatybilne" po obydwu stronach, zaś jeśli chodzi o wywoływanie procek, to stworzyłem po prostu API do programu głównego i wszystko śmiaga. Jedna funkcja w programie głównym wysyła adresy innych procedur, po czym dll może się odwołać do tej, co chce. Ale fakt, trzeba trochę nad tym posiedzieć, popróbować. Ja w sumie dużo różnych metod próbowałem, ta jak na razie okazała się skuteczna. Tak jak mówię, jak Epsisoft skończy prace nad PMP3 1.5, to będę mógł pokazać jak to zrealizowałem.

0

Aplikacja nie może podać do dll adresu funkcji?
A tak nie można:

w dll mamy funkcję: Setfptr(fptr *pfun, ...);
w exe wywołuję: Setfptr(funkcyjka, ...);

Albo ten dll pobiera sobie ją samodzielnie:
GetModuleHandle(NULL) i GetProcAddress

0

No prawie, tylko dwie sprawy:
1) Jeśli zamierzasz "eksportować" do dll'a wiele procek, a potem jeszcze może sięto zmieniać, to takie bezpośrednie przekazywanie nie jest wygodne. Rozwiązałem to tak, że eksportuję uniwersalną funkcję, która na podstawie podania nazwy funkcji w API dopiero zwraca adres docelowej funkcji/procedury, a tą funkcję "podającą adresy" przekazuję w procedurze inicjującej działanie wtyczki.
2) Pytanie dotyczy do Delphi, tutaj wskaźniki nie zaczynają się od * ;)

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