на языках, которые могут ссылаться на С++

Пока я размышлял на эту тему, мне показалось, что если язык реализован на C++, то он вполне может иметь механизм привязки к C++. Насколько я помню, Java проходит через JNI, хотя я действительно не помню, проходит ли он через C++ или простой C.

Однако кажется, что в целом языки не связаны с C++ и доступны для C++ только через C по разным причинам.

Итак, из любопытства,

Какие языки могут быть связаны с C++, как и в какой степени?

(Никакой кредит для вышеупомянутого моста C, если он не сделан элегантным или интересным способом, как Boost.Python)


person Ellery Newcomer    schedule 07.03.2009    source источник


Ответы (3)


Примечание: ABI включает изменение имени, а также соглашение о вызовах, требования к среде и т. д. EABI (здесь не рассматривается) зависит от платформы, но обычно стандартизирован для каждой платформы (хотя это не гарантируется) и не не страдает от проблем вариационного EABI (потому что он мало что меняет). Обратитесь к ABI в Википедии, чтобы получить дополнительную информацию по этому вопросу.

Связывание с C++ маловероятно, поскольку ABI не определен. Таким образом, имена символов могут меняться по желанию производителя компилятора. Например, GCC делает это иначе, чем компилятор MS. Даже с одним и тем же компилятором ABI могут различаться между версиями (как в случае с некоторыми версиями GCC).

Однако связывание с C++ возможно. Программы на C++ часто ссылаются на другие программы на C++, потому что обе компилируются одним и тем же компилятором (или, по крайней мере, компиляторами, использующими один и тот же ABI). Если известен ABI, приложения, отличные от C++, могут ссылаться на приложения C++.

Связать с C очень просто. Это связано с тем, что ABI C более стабилен, чем ABI C++ для большинства платформ. Это связано с простотой C по сравнению с C++. Поскольку C++ может экспортировать символы C, обходя проблему с ABI C++, вы иногда видите, что библиотеки C++ экспортируют символы C, которые позволяют взаимодействовать с базовыми объектами C++ без проблем с искажением имен, совместимостью ссылок и перспективой. Однако это не позволяет вам легко использовать библиотеку C++ через интерфейс C с интерфейсом C++.

Но вы можете использовать интерфейс C++, используя экспорт C. Библиотека может предоставить некоторые классы в файлах заголовков, которые обертывают для вас экспорт C. Это больше работы для авторов библиотек (и может вызвать некоторые проблемы, потому что DRY обычно не практикуется с этой техникой), но дает большую пользу пользователям библиотек (которые могут выбирать между обоими интерфейсами, не беспокоясь о проблемах с компоновкой!). Для других языков авторы библиотек могут предоставить интерфейсы, такие как файлы заголовков C++, которые сами имеют дело с экспортом C. (Тогда у вас есть преимущество использования нативных классов и тому подобного.)

person strager    schedule 07.03.2009
comment
Да; GCC меняет имена при внесении несовместимых изменений (например, с 4.2.x на 4.3.x, IIRC). - person Jonathan Leffler; 07.03.2009
comment
Интересный анекдот про GCC. - person Ellery Newcomer; 07.03.2009
comment
Переход с 3.3 на 3.4 стал серьезным прорывом в ABI. - person Johannes Schaub - litb; 07.03.2009
comment
Не уверен, почему я теряю голоса здесь. Кто-нибудь хочет объяснить? - person strager; 07.03.2009
comment
Я на самом деле тоже задавался этим вопросом. Понятия не имею, но вот голосование :-). - person Todd Gamblin; 07.03.2009
comment
я также проголосовал за вас. однако это связано с тем, что ABI C хорошо определен и стабилен, в отличие от ABI C++, это не совсем правильно. как C, так и C++ ABI могут быть определены в рамках одной платформы + компилятора. нет никакой разницы между определенностью C и C++. просто C намного проще. - person Johannes Schaub - litb; 07.03.2009
comment
и, таким образом, имеет гораздо меньше проблем с различными ABI. как говорит Джонатан в другом ответе, изменение имени на самом деле является лишь небольшой частью ABI (и, как вы сказали сейчас). есть еще, например, прохождение реестра и так далее. ABI C не определен ни для разных платформ, ни для компиляторов. - person Johannes Schaub - litb; 07.03.2009
comment
@litb, я помню, где-то читал, что ABI C определен в стандарте (вероятно, C89 и C99). Может быть, определено только искажение имени? - person strager; 07.03.2009
comment
я не знаю никаких правил ABI, установленных стандартом. я был бы очень удивлен, если бы стандарт C приложил сюда какую-либо силу. в любом случае, конечно, теперь мне нравится твой ответ намного больше. пальцы вверх :) - person Johannes Schaub - litb; 07.03.2009

Не существует языка, который мог бы сделать это хорошо, потому что стандарт C++ не укажите схему изменения имени. Из-за этого разные компиляторы могут изменять имена по-разному, и не существует единого способа связывания с двоичными файлами C++.

Причина, по которой так много вещей может быть связано с C, заключается в том, что C имеет простую и непротиворечивую связь. Функция foo называется foo в объектном файле. Точно так же вещи могут быть достаточно хорошо связаны с Fortran, потому что foo является одним из foo, FOO, foo_ или foo__.

Вот почему существует так много генераторов оболочек для объектов C++ (SWIG, Boost.Python, SIP и т. д.). Они определяют интерфейс как набор вызовов C именно потому, что это упрощает компоновку.

Еще кое-что, о чем следует помнить, это то, хотите ли вы действительно связываться напрямую с библиотеками C++. Многие генераторы оболочек предоставляют множество параметров политики при создании оболочек. Помните, что вызовы C сводятся только к функциям, но вызовы C++ обычно имеют много объектно-ориентированной семантики, с которой вам нужно ориентироваться. Вам нужно указать, как ваши объекты C++ должны быть собраны мусором в основном языке, как вещи копируются, где находятся vptrs, как размещаются объекты, где объекты распределяются, а также все тонкие различия между объектной моделью основного языка и этой моделью. С++.

Я знаю, что это звучит идеально, просто связать библиотеку C++ и покончить с этим, но это не так просто, и вам в любом случае понадобится нечто большее, чем просто прямая связь.

person Todd Gamblin    schedule 07.03.2009
comment
И стандарт не должен указывать схему изменения имен, потому что слишком много других вещей, которые должны быть указаны для взаимодействия между различными реализациями C++ (разметка объектов в памяти и vptrs, для начала, и это только верхушка очень большой айсберг!) - person Jonathan Leffler; 07.03.2009
comment
да -- ОЧЕНЬ хороший момент. Я оставил это для длинного ответа - см. выше и не стесняйтесь добавлять то, что вам не хватает! Этот вопрос поднимался очень часто, и было бы неплохо получить ответ, объясняющий людям, почему они этого не хотят! - person Todd Gamblin; 07.03.2009

Недавно просматривали SWIG?

person greyfade    schedule 07.03.2009
comment
Не в последнее время, но я знаю о его существовании. - person Ellery Newcomer; 07.03.2009
comment
О да, и +1 за фактический ответ на мой вопрос. Вроде, как бы, что-то вроде. - person Ellery Newcomer; 07.03.2009