Jak kod napisany w jednym języku jest wywoływany z innego języka

To jest pytanie, na które zawsze chciałem znać odpowiedź, ale nigdy tak naprawdę nie zadałem.

Jak kod napisany przez jeden język, szczególnie język interpretowany, jest wywoływany przez kod napisany przez język skompilowany.

Na przykład, powiedzmy, że piszę grę w C++ i zlecam niektóre zachowania AI do napisania w Scheme. W jaki sposób kod napisany w Scheme dociera do punktu, który jest użyteczny przez skompilowany kod C++? Jak jest używany przez kod źródłowy C++ i jak jest używany przez skompilowany kod C++? Czy jest jakaś różnica w sposobie jej używania?

Powiązane

Jak wiele języków wchodzi w interakcje w jednym projekcie?

Author: Community, 2009-05-08

7 answers

Nie ma jednej odpowiedzi na pytanie, które działa wszędzie. Ogólnie rzecz biorąc, odpowiedź jest taka, że oba języki muszą uzgodnić "coś" - zestaw lub reguły lub "protokół wywołujący".

Na wysokim poziomie każdy protokół musi określać trzy rzeczy:

  • "discovery": jak znaleźć o sobie nawzajem.
  • "linkowanie": jak nawiązać połączenie (po tym, jak dowiedzą się o sobie nawzajem).
  • "Inwokacja": jak właściwie zwracać się do siebie nawzajem.

The szczegóły zależą w dużej mierze od samego protokołu.

Czasami oba języki spiskują, aby współpracować. Czasami oba języki zgadzają się na obsługę jakiegoś zewnętrznego protokołu. W dzisiejszych czasach często zaangażowany jest również system operacyjny lub" środowisko uruchomieniowe " (. NET i Java). Czasami zdolność idzie tylko w jedną stronę ("A "może wywołać" B", ale" B "nie może wywołać"A").

Zauważ, że jest to ten sam problem, który napotyka każdy język podczas komunikacji z systemem operacyjnym. Jądro Linuksa nie jest napisane w schemat, wiesz!

Zobaczmy typowe odpowiedzi ze świata Windows:

  • C with C++: C++ używa zniekształconej ("zniekształconej") odmiany "protokołu C". C++ może wywoływać do C, A C może wywoływać do C++ (chociaż nazwy mogą być czasami dość niechlujne i może potrzebować zewnętrznej pomocy w tłumaczeniu nazw). To nie tylko Windows; jest to na ogół prawdą na wszystkich platformach, które obsługują oba. Najpopularniejszy system operacyjny używa "protokołu C" jako cóż.

  • VB6 vs. większość języków : preferowaną metodą VB6 jest "protokół COM". Inne języki muszą być w stanie zapisywać obiekty COM, aby mogły być użyteczne z VB6. VB6 moĹźe rĂłwnieĹź wytwarzaÄ ‡ obiekty COM (choÄ ‡ nie kaĹźda moĺźliwa odmiana obiektów COM).

    VB6 może również rozmawiać z bardzo ograniczoną odmianą "protokołu C", a następnie tylko wykonywać połączenia na zewnątrz: nie może tworzyć obiektów, z którymi można rozmawiać bezpośrednio przez "protokół C".

  • . NET języki: wszystkie języki. NET komunikują się kompilując do tego samego języka niskiego poziomu (IL). Runtime zarządza komunikacją i z tego punktu widzenia wszystkie wyglądają jak ten sam język.

  • VBScript vs. other languages: VBScript może mówić tylko o podzbiorze protokołu COM.

Jeszcze jedna uwaga: SOAP "Usługi internetowe" to tak naprawdę "protokół wywołujący", podobnie jak wiele innych protokołów internetowych, które stają się popularne. W końcu chodzi o rozmowa z kodem napisanym w innym języku (i uruchomienie w innym polu na to!)

 13
Author: Euro Micelli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-08 17:58:32

Zazwyczaj kod C++ wywoła interpreter dla języka skryptowego. Stopień interakcji między skompilowanym i skryptowym kodem zależy od interpretera, ale zawsze istnieje sposób przekazywania danych między nimi. W zależności od interpretera, możliwe jest manipulowanie obiektami po jednej stronie z drugiej strony, jak na przykład funkcja C++ wywołująca metodę na obiekcie Ruby. Może być nawet sposób na kontrolowanie wykonania jednego od drugiego.

 4
Author: Pesto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-08 17:20:56

Istnieje protokół komunikacji modułów. Oto szeroki przegląd tego, jak to działa:

  1. Biblioteka jest tworzona dla kodu, który chcesz "udostępnić". Są one powszechnie nazywane DLL lub SOs w zależności od platformy.
  2. każda funkcja, którą chcesz ujawnić (punkt wejścia) będzie dostępna dla świata zewnętrznego, aby ją powiązać. Istnieją protokoły, jak wiązać, takie jak Konwencja wywołująca, która określa kolejność przekazywania parametrów, kto czyści stos, ile parametrów jest zapisywanych w rejestrach i jakie, itd. Zobacz cdecl, stdcall, etc dla przykładów wywołania konwencji tutaj .
  3. moduł wywołujący połączy się statycznie lub dynamicznie z biblioteką współdzieloną.
  4. gdy wywołująca Biblioteka zostanie powiązana z biblioteką współdzieloną, może określić, że chce powiązać z określonym punktem wejścia. Zazwyczaj odbywa się to z nazwy, jednak większość platform oferuje również opcję wiązania przez indeks (szybsze, ale bardziej kruche jeśli twój moduł się zmieni, a punkty wejścia zostaną uporządkowane).
  5. będziesz również ogólnie deklarować funkcję, którą chcesz wywołać w swoim module, aby twój język mógł wykonywać statyczne sprawdzanie typów, wiedzieć, jaka jest konwencja wywołania itp.

Dla Twojego scenariusza wywołania schematu z C++, interpreter schematu najprawdopodobniej eksportuje funkcję, która dynamicznie wiąże się z funkcją/obiektem schematu i wywołuje ją. Jeśli moduł Scheme jest skompilowany to prawdopodobnie ma możliwość eksportowanie punktu wejścia, aby twój moduł C++ mógł się z nim wiązać. Nie jestem zbyt zaznajomiony z schematem, więc ktoś inny może prawdopodobnie odpowiedzieć na specyfikę tego konkretnego wiązania lepiej niż ja.

 4
Author: Adam Markowitz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-08 17:29:59

Można również zintegrować oba środowiska bez konieczności kompilowania biblioteki interpretera wewnątrz pliku wykonywalnego. Zachowujesz EXE i Scheme exe jako oddzielne programy w systemie. Z głównego exe możesz napisać kod schematu do pliku, a następnie użyć system() lub exec (), aby uruchomić interpreter schematu. Następnie analizuje się wynik interpretera scheme.

Podejście zaproponowane powyżej utrzymuje exe oddzielnie i nie musisz się martwić o zależności 3rd party, mogą być znaczące. Również problemy pozostają zawarte w jednym exe lub innym.

Jeśli uruchomienie oddzielnego exe nie spełnia twoich wymagań wydajnościowych, możesz opracować protokół, w którym interpreter Scheme stanie się serwerem. Musisz napisać kilka funkcji schematu, które czekają na wejście na gnieździe lub pliku, ewalować to wejście, a następnie wypisać wynik do tego samego gniazda lub innego pliku. Kolejną iteracją tego jest przyjrzenie się istniejącym serwerom, które mogą już działać na Twoim interpreterze, na przykład apache posiada moduły umożliwiające pisanie kodu w wielu językach.

 2
Author: Marius Seritan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-08 17:37:28

Jeśli naprawdę szukasz narzędzi do zrobienia czegoś takiego, odpowiedź a la Adama, zobacz swig .

 1
Author: Matt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-08 17:34:04

Z teoretycznego punktu widzenia, gdy program A potrzebuje użyć zasobów (klasy / funkcje / etc) z programu B, chodzi o przekazanie pewnych informacji z A do B i odzyskanie pewnych informacji lub wykonanie pewnych akcji. Musi więc istnieć sposób zapewniony przez B, który pozwoli A przekazać informacje i uzyskać wynik.

W praktyce zwykle na ramieniu języków leży obsługa tego procesu: język B (program B jest napisany) wygeneruje protokół i utworzy zasoby w B jest dostępny w określony sposób, a następnie język a (napisany w nim program a) zapewni pewne narzędzie/Framework, aby pomóc wywołać otwarte zasoby i uzyskać wyniki zgodnie z protokołem B.

Aby być bardziej szczegółowym dla Twojego pytania, dla języków interpretowanych Proces jest dość uniwersalny, protokół jest zwykle wśród linii parametru wiersza poleceń, żądania HTTP i innych sposobów przesyłania zwykłego tekstu. Weźmy pierwszy przykład, program B otrzyma połączenie z żądania HTTP jako input, a następnie przetworzyć żądanie stamtąd. Rzeczywisty format wejściowy jest całkowicie określony przez program B.

Rzeczy takie jak SOAP itp., są tylko sposobem na regulowanie programów w celu przyjęcia wkładu w powszechnie uzgodnionym standardzie.

 1
Author: FlyinFish,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-08 20:08:42

Minęło około dekady, ale zrobiłem dokładnie to dla mojego maturzysty capstone(cóż, zbudowałem back-propogating neural network W C i użyłem programu scheme do nauczania tego). Wersja schematu, której używałem, miała kompilator oraz intepreter i udało mi się go zbudować jako .plik o. Nie znam wersji programu, którą uruchomiłem, ale wygląda na to, że RScheme zmieni Twój kod programu w C.

 1
Author: Matt Poush,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-08 20:26:18