Odpalenie funkcji z innego unit

0

Jest możliwość odpalenia funkcji z innego unitu w paskalu, ale bez wsadzania całego tego unita w uses?

Chodzi o coś takiego:
mamy dwa unity, z których pierwszy jest bazowym 'baza', czyli ten drugi go używa: 'spec'.

i teraz pojawia się sytuacja, że potrzebuję wywołać tylko jedną funkcję w 'baza', która jest jednak 'spec',
a nie chcę tworzyć cyrkulacji, tz. deklarować spec w bazia.

Wydawało mi się że tu wystarczy zadeklarować tę zew. funkcję za pomocą external, o tak:

function super(a,b,c:Integer): Integer; external;

No, ale to nie działa, niestety - kompilator paskala jest zbyt głupi, bowiem żąda definicji w tym samym module.
Myślałem że to pójdzie, bo np. c ogarnia to bez problemu, co nie jest wcale dziwne - przecież to jest bagatelka: wystarczy zignorować problem, bowiem linker bez problemu znajdzie potem co mu potrzeba.

0

Podaj nazwę środowiska i ew. kompilatora, z którego korzystasz.

0

nie. Jak chcesz coś użyć z konkretnego unitu to musisz go dodać do uses

0
abrakadaber napisał(a):

nie. Jak chcesz coś użyć z konkretnego unitu to musisz go dodać do uses

Wtedy to jest do d**y, bo ja nie chcę tego krzyżować... np. lokalne funkcje i zmienne mogą być identycznie ponazywane w obu unitach, więc wtedy sieczka z tego wyjdzie.

Jak wywołać funkcję z drugiego modułu - najniższym kosztem, a i w ogóle bez ruszania tego drugiego!

Powinna istnieć np. taka możliwość:
unitx.fun(a,b,c);

gdzie unitx to nazwa obcego moduły, w którym jest funkcja fun.
Proste i oczywiste.

0

Wydawało mi się że tu wystarczy zadeklarować tę zew. funkcję za pomocą external, o tak:

function super(a,b,c:Integer): Integer; external;

No, ale to nie działa, niestety - kompilator paskala jest zbyt głupi, bowiem żąda definicji w tym samym module.

Żaden kompilator nie żąda definicji funkcji w tym samym module, jeśli jest ona oznaczona modyfikatorem external.

Wtedy to jest do d**y, bo ja nie chcę tego krzyżować... np. lokalne funkcje i zmienne mogą być identycznie ponazywane w obu unitach, więc wtedy sieczka z tego wyjdzie.

Sam sobie podsunąłeś rozwiązanie:

Powinna istnieć np. taka możliwość:

unitx.fun(a,b,c);

gdzie unitx to nazwa obcego moduły, w którym jest funkcja fun.
Proste i oczywiste.

Bez problemu możesz używać nazw modułów jako przestrzeni nazw. A jeśli zachodzić będzie kolizja identyfikatorów to kompilator wybierze pierwszą funkcję z brzegu.

0
furious programming napisał(a):

Wydawało mi się że tu wystarczy zadeklarować tę zew. funkcję za pomocą external, o tak:

function super(a,b,c:Integer): Integer; external;

No, ale to nie działa, niestety - kompilator paskala jest zbyt głupi, bowiem żąda definicji w tym samym module.

Żaden kompilator nie żąda definicji funkcji w tym samym module, jeśli jest ona oznaczona modyfikatorem external.

Nie kompiluje się takie coś, bowiem to 'external' w paskalu działa podobnie do forward (abo wręcz identycznie, pomijając detale), czyli jedynie opóźnia nieuniknioną katastrofę.

Wtedy to jest do d**y, bo ja nie chcę tego krzyżować... np. lokalne funkcje i zmienne mogą być identycznie ponazywane w obu unitach, więc wtedy sieczka z tego wyjdzie.

Sam sobie podsunąłeś rozwiązanie:

ale tylko w przypadku gdy użyjemy uses.

Przykładowo:
użycie samego:
MessageBox, odpali zwykle jakiś śmieć zaproponowany przez autorów danego środowiska, w którym kompilujemy;

natomiast:
windows.MessageBox odpali ten systemowy - z windowsa,
niemniej pod warunkiem, że wsadzamy cały unit windows, znaczy musimy wcześniej napisać: uses windows;

0
wil napisał(a):

Nie kompiluje się takie coś, bowiem to 'external' w paskalu działa podobnie do forward (abo wręcz identycznie, pomijając detale), czyli jedynie opóźnia nieuniknioną katastrofę.

No dobrze, ale jest różnica pomiędzy nieuniknioną katastrofą a żądaniem zdefiniowania funkcji w tym samym module. I też niekoniecznie – np. FPC dokończy kompilację, pod warunkiem, że owa funkcja nie będzie nigdzie w kodzie użyta. No ale nie po to się ją deklaruje, żeby jej nie używać.

FPC umożliwia linkowanie, ale nigdy tego nie używałem, więc trzeba by poczytać.

wil napisał(a):

ale tylko w przypadku gdy użyjemy uses.

A masz inne rozwiązanie? Jeśli jak twierdzisz nie ma opcji późniejszego zlinkowania definicji to pozostaje jedynie zadeklarowanie modułu i skorzystanie z jego nazwy w celu odróżnienia elementów o takiej samej nazwie.

0

żaden ze znanych mi języków nie pozwala korzystać z funkcji z modułów, które nie są dodane do modułu, w którym chcesz ją wywołać - np. c# ma using, c++ i php include także twoje płacze są po prostu śmieszne. Jak ci tak nie pasuje to zmień język na jakiś inny.

BTW możesz wydzielić tą funkcję do osobnego modułu i podlinkować ten nowy moduł zarówno do starego jak i w docelowym.
BTW2 external jest do czegoś innego niż sobie wymyśliłeś

0

Mój pomysł: Wyrzuć funkcję, którą chcesz użyć do oddzielnego usesa

0
abrakadaber napisał(a):

żaden ze znanych mi języków nie pozwala korzystać z funkcji z modułów, które nie są dodane do modułu, w którym chcesz ją wywołać - np. c# ma using, c++ i php include także twoje płacze są po prostu śmieszne. Jak ci tak nie pasuje to zmień język na jakiś inny.

Mylisz się.
W C, zatem i w C++ - oczywista!, wystarczy tak napisać - dowolnym miejscu i czasie:

moduł baza.cpp:
...
int siekiera(int a, int b); // to jest tylko deklaracja - nie ma znaczenia gdzie finalnie ta funkcja jest definiowana

// i teraz używasz tę funkcję - jak każdą inną! np.:

int tnij(int a, int b )
{
int c = siekiera(a+b - 3, 17);
return c - a;
}

W związku z tym jest wniosek do autorów kompilatorów, a zwłaszcza do tych od Free Pascala:
należy wprowadzić następujące rozszerzenie:

goła deklaracja funkcji/procedury ze znacznikiem external nie może powodować błędów (na etapie komplilacji).

Konkretnie - zapis typu:

function super(a,b,c:Integer): Integer; external;

i plus dalsze dowolne użycie w ten sposób zadeklarowanej funkcji
ma działać, znaczy moduł ma się kompilować poprawnie.

Po prostu: ta funkcja musi istnieć ale gdziekolwiek - w ramach całej i finalnie składanej aplikacji,
czyli w dowolnym module, albo też i w załączonych bibliotekach, zwykle typu: lib, obj, dcu, itp.
No, czyli ma to być tak, czy inaczej w sekcji uses, ale w dowolnym unicie danego projektu - niekoniecznie w tym jednym, w którym to jest akurat deklarowane i używane!

0

Stąd wniosek @wil kompletnie nie znasz Delphi / Free Pascala ale próbujesz forsować wprowadzanie w nim zmian. Nikt za cholerę nie wie w czym przeszkadza dodanie do uses. Moduły mogą się wzajemnie do siebie odnosić jeżeli zadeklarujesz w spec pod** interface** uses ..., baza; a w baza pod implementationuses ..., spec;.

0
kAzek napisał(a):

Stąd wniosek @wil kompletnie nie znasz Delphi / Free Pascala ale próbujesz forsować wprowadzanie w nim zmian. Nikt za cholerę nie wie w czym przeszkadza dodanie do uses. Moduły mogą się wzajemnie do siebie odnosić jeżeli zadeklarujesz w spec pod** interface** uses ..., baza; a w baza pod implementationuses ..., spec;.

Pewnie komuś też istotnie przeszkadzało... no i dlatego wymyślono potem C, hehe!

0

Pytanie dodatkowe w ramach tematu:
czy istnieje możliwość (jakakolwiek!) zdefiniowania obiektu (klasy) w paskalu,
którego metody nie będą definiowane w ramach jednego unitu (pomijając importy oczywista), lecz w kilku różnych?

Np. mając klasę z dwoma procedurami - nietrudno sobie wyobrazić sytuację:
pierwsza procedura jest zapisana w unicie: a.pas, a druga w b.pas - można tak?

1

Oczywiste pytanie, które się nasuwa to po jaki ****?
Jeśli masz klasę, która "nie mieści się" w jednym pliku to masz do d**y klasę a nie środowisko.

Rozumiem, że jesteś kolejnym, który z jakiegoś powodu "musi" pisać w pascalu (nie ważne czy to fpc czy delphi) i zamiast wziąć i napisać to co ma do napisania to będziesz teraz wymyślał cuda i udowadniał wszem i wobec, jaki to ten język est do d**y. Żyjemy w wolnym kraju i jak ci się coś nie podoba to nie musisz tego robić - pracę czy studia można zmienić, a jak delphi to twoje hobby to czas się zająć np. pasaniem kóz - to dużo mniej stresujące zajęcie.

0

Wydziel pewne długie (czy tam mało czytelne) definicje metod do plików .inc i dołącz je do modułu z deklaracją klasy (w sekcji implementation), bo po to one istnieją. W ten sposób da się podzielić dowolny kod – nie tylko zawartość klas.

Zobacz z ilu takich plików składa się biblioteka standardowa i ew. komponentów w środowisku, którego używasz. Bieżąca wersja Lazarusa posiada ich łącznie 3563 (z ciekawości sprawdziłem).

Poza tym zgadzam się z @abrakadaber – celowo doszukujesz się różnic pomiędzy Pascalem a C, a następnie urządzasz jakieś cyrki w swoich wątkach. Obstawiam, że nie masz 10 lat, więc jeśli chcesz wiedzieć jak coś w Pascalu działa to po prostu zapytaj, bez tej całej infantylnej otoczki.

0
abrakadaber napisał(a):

Oczywiste pytanie, które się nasuwa to po jaki ****?
Jeśli masz klasę, która "nie mieści się" w jednym pliku to masz do d**y klasę a nie środowisko.

Rozumiem, że jesteś kolejnym, który z jakiegoś powodu "musi" pisać w pascalu (nie ważne czy to fpc czy delphi) i zamiast wziąć i napisać to co ma do napisania to będziesz teraz wymyślał cuda i udowadniał wszem i wobec, jaki to ten język est do d**y. Żyjemy w wolnym kraju i jak ci się coś nie podoba to nie musisz tego robić - pracę czy studia można zmienić, a jak delphi to twoje hobby to czas się zająć np. pasaniem kóz - to dużo mniej stresujące zajęcie.

Oj! Nie panikujcie, dzieci. :)
To są problemy wirtualne, tz. takie z dziedziny teorii (języków) programowania.

W praktyce zawsze można pokombinować;
niemniej nigdy nie wyjdziesz ponad ramy tejże teorii właśnie, stąd sens rozważania tego typu abstrakcyjnych, czy też skrajnych problemów.

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