Pytanie Zapoznaj się z interfejsem funkcji obcych (FFI) i powiązaniem języka


Mieszanie różnych języków programowania było od dawna czymś, czego nie całkiem rozumiem. Według ten artykuł Wikipedii, obcy interfejs funkcji (lub FFI) można zrobić na kilka sposobów:

  1. Wymaganie, aby funkcje języka gościa, które mają być wywoływane w języku hosta, były określone lub implementowane w określony sposób; często przy użyciu jakiejś biblioteki kompatybilności.
  2. Używanie narzędzia do automatycznego "zawijania" funkcji języka gościa za pomocą odpowiedniego kodu kleju, który wykonuje niezbędne tłumaczenie.
  3. Korzystanie z bibliotek opakowania
  4. Ograniczenie zestawu funkcji języka hosta, które mogą być używane w wielu językach. Na przykład funkcje C ++ wywoływane z C nie mogą (ogólnie) zawierać parametrów referencji lub wyrzucać wyjątków.

Moje pytania:

  1. Jakie są różnice między 1, 2 i 3 sposoby? Wygląda na Ja wszyscy musimy skompilować kod w niektórych języku nazywany biblioteka z plikami obiektowymi i nagłówkiem pliki, które są następnie wywoływane przez język wzywający.
  2. Jedno źródło, które łączy mówi, wdrażanie FFI można zrobić w kilka sposobów:

    • Wymaganie wywoływanych funkcji w języku docelowym implementuje a   określony protokół.
    • Wdrażanie biblioteki otoki, która przyjmuje określony język   funkcja i "opakowuje" ją za pomocą kodu do konwersji danych do / z   konwencje językowe wysokiego poziomu.
    • Wymaganie funkcji deklarowanych jako natywne do korzystania z podzbioru funkcji wysokiego poziomu (który jest zgodny z językiem niskiego poziomu).

    Zastanawiałem się, czy pierwszy sposób w połączone źródło jest takie samo jak pierwszy sposób w Wikipedii?

    Co oznacza trzecia droga w tym źródło oznacza? Czy odpowiada on czwartej drodze w Wikipedii?

  3. W  to samo źródło, porównując trzy wymienione sposoby, wydaje się mówić zadanie wypełnienia luki między oba języki są stopniowo przesunięte z języka nazwanego do języka dzwoniącego. byłam zastanawiasz się, jak to zrozumieć? Czy ta zmiana dotyczy również czterech sposobów w Wikipedii?
  4. Wiązanie języka i FFI równoważne pojęcia? Jak się mają powiązane i różne?

    wiązanie z języka programowania   do biblioteki lub usługi OS to API   świadczenie tej usługi w   język.

  5. Zastanawiałem się, w jaki sposób w cytacie z Wikipedii lub ze źródła, do którego należy każdy z poniższych przykładów?

Dzięki za twoje oświecenie! Z poważaniem!


16
2018-03-26 07:26


pochodzenie




Odpowiedzi:


Może być konkretny przykład pomoże. Przyjmijmy język hosta jako Python, a język gościa jako C. Oznacza to, że Python będzie wywoływał funkcje C.

  1. Pierwszą opcją jest napisanie biblioteki C w określony sposób. W przypadku Pythona standardowym sposobem byłoby zapisanie funkcji C z pierwszym parametrem Py_Object * wśród innych warunków. Na przykład (stąd):

    static PyObject *
    spam_system(PyObject *self, PyObject *args)
    {
        const char *command;
        int sts;
    
        if (!PyArg_ParseTuple(args, "s", &command))
            return NULL;
        sts = system(command);
        return Py_BuildValue("i", sts);
    }
    

    jest funkcją C, którą można wywołać z Pythona. Aby to działało, biblioteka musi być napisana z myślą o kompatybilności z Pythonem.

  2. Jeśli chcesz użyć istniejącej biblioteki C, potrzebujesz innej opcji. Jednym z nich jest posiadanie narzędzia, które generuje okłady z istniejącej biblioteki w formacie odpowiednim do konsumpcji przez język hosta. Brać Haust które można wykorzystać do wiązania wielu języków. Biorąc pod uwagę istniejącą bibliotekę C możesz użyć swig do efektywnego generowania kodu C, który wywołuje twoją istniejącą bibliotekę, zgodnie z konwencjami Pythona. Widzieć przykład do budowania modułu Pythona.

  3. Inną opcją dla istniejącej już biblioteki C jest wywołanie jej z biblioteki Pythona, która skutecznie owija połączenia w czasie wykonywania, np. ctypes. Podczas gdy w opcji 2 kompilacja była konieczna, to nie tym razem.

Inną rzeczą jest to, że istnieje wiele opcji (które nakładają się) dla wywoływania funkcji w jednym języku z innego języka. Istnieją FFI (równoważne z powiązaniami językowymi, o ile wiem), które zwykle dotyczą połączeń między wieloma językami w tym samym procesie (jako część tego samego pliku wykonywalnego, że tak powiem) i istnieją środki komunikacji międzyprocesowej (lokalne i sieciowe). Rzeczy takie jak CORBA i Web Services (SOAP lub REST) ​​i COM + oraz zdalne wywołania procedur są w ogóle drugą kategorią i nie są postrzegane jako FFI. W rzeczywistości najczęściej nie przepisują żadnego konkretnego języka, który mógłby być użyty po obu stronach komunikacji. Ujmowałbym je luźno jako opcje IPC (komunikacja międzyprocesowa), choć jest to uproszczenie w przypadku opartych na sieci APi takich jak CORBA i SOAP.

Będąc na twojej liście, zaryzykowałbym następujące opinie:

  • Architektura brokera obiektów wspólnych: IPC, a nie FFI
  • Wywołanie C w C ++, przez extern "C" deklaracja w C ++, aby wyłączyć wymazywanie nazw. ****
  • Wywołanie C w Matlab, przez interfejs MATLAB do bibliotek współdzielonych Opcja 3 (podobne do ctypów)
  • Wywołanie C w Matlab, poprzez tworzenie plików MEX języka C / C ++ Opcja 2 (podobna do swigu)
  • Wywołanie Matlab w C, przez kompilator mcc Opcja 2 (podobna do swigu)
  • Wywołanie C ++ w Javie, przez JNI i wywoływanie Java w C ++ przez JNI Opcja 3 (podobne do ctypów)
  • Wywołanie C / C ++ w innych językach, Używanie SWIG Opcja 2 (łyk)
  • Wywołanie C w Pythonie, według Ctypes Opcja 3 (ctypes)
  • Cython Opcja 2 (podobna do swigu)
  • Wywołanie R w Pythonie, przez RPy Opcja 3 (podobne do ctypów) w części, a częściowo o wymianę danych (nie FFI)

Następne dwa nie są w ogóle obcymi interfejsami funkcji, ponieważ termin ten jest używany. FFi dotyczy interakcji między językami programowania i powinno umożliwiać tworzenie dowolnej biblioteki (z odpowiednimi ograniczeniami) z jednego języka dostępnego dla drugiego. Konkretna biblioteka dostępna z jednego języka nie tworzy FFI.

  • Programowanie powiązań językowych z OpenGL z różnych języków
  • Wiązania dla biblioteki C z różnych języków

13
2018-03-30 16:26



+1 miła odpowiedź. Jedna uwaga: "Wywołanie C w MATLAB poprzez tworzenie plików MEX" jest bardziej podobne do "Opcji 1", jest odpowiednikiem napisania rozszerzenia Pythona za pomocą jego API C. Tworzysz regularną bibliotekę współdzieloną ze specjalną procedurą bramy, która odbiera mxArray* parametry. Jeśli chodzi o "wywoływanie MATLABa w C przy użyciu kompilatora mcc", to tak naprawdę nie jest to FFI, ponieważ jest to po prostu kod C wywołujący inny kod C (kompilator MCC generuje regularne biblioteki współdzielone). - Amro
Inną opcją, o której nie wspomniano, jest "wywoływanie MATLAB-a w C przy użyciu MATLAB Engine", który jest podobny do "Umieszczanie w Pythonie" aby kontynuować analogię (tak samo jak wywoływanie Java w C przy użyciu interfejsu JNI) - Amro
Muhammad, dziękuję! Zajęło mi tyle czasu, aby wrócić i nadać sens większości twoich odpowiedzi. Moje przeprosiny. "Następne dwa nie są w ogóle obcymi interfejsami funkcyjnymi, ponieważ termin ten jest używany ... Dana biblioteka dostępna z jednego języka nie tworzy FFI". Na przykład, jeśli mam rację, OpenGL (lub Kair jako powiązany w moim poście) jest zaimplementowany w bibliotece C i jak jest zaimplementowane jego powiązanie w innym języku (np. Python)? Również jeden z trzech sposobów FFI wymienionych na początku postu? - Tim
Również "Wywoływanie C ++ w Javie, przez JNI i wywoływanie Java w C ++ przez JNI Option 3 (ctypes-like)", wydaje mi się, że JNI jest jak opcja 1. - Tim