ПрограммированиеФорумОбщее

extern "C". Зачем нужно???

#0
14:06, 26 окт 2006

Пересмотрел всю литературу, доходчивого и детального объяснения об использовании extern "C" не нашел(может туго доходил:)). Подскажите что это такое и с чем его едят. Буду благодарен

#1
14:12, 26 окт 2006

Я знаю одно примение, сугубо практическое :-) При экспорте функций функции определяются без декораций. Т.е. название функции будет соответстовать ее имени - TestFunc, а не что-то вроде @@TestFuncYYWW и прочий бред.
Того же эффекта можно добиться если включить DEF файл в проект.

#2
14:18, 26 окт 2006

name mangling не учитывается, т.е. если ты заявил что тебе нужно extern "C" SomeExternStaff, то в либах/ДЛЛ будет искаться именно "SomeExternStaff" а не что-то вроде "@@_SomeExternStaff".

Особенно полезно когда экспортишь всякое в ДЛЛ -- схемы декорации имён отличаются от компилера к компилеру.

#3
14:55, 26 окт 2006

FireFly
Ghost Dragon
Аккуратнее с декорациями. extern "C" все равно завтавляет декорировать функции в соответствии с calling conventions (cdecl, fastcall, stdcall - см. в MSDN). Но убирается декорирование С++, описывающее аргументы функции

#4
14:59, 26 окт 2006

COOLibin

если до сих пор непонятно откуда растут корни, поясняю полностью.
издревле повелось, что компиляторы с "продвинутых" и общеупотребительных языков программирования (asm, c, c++ и др.) разделяют код между т.н. юнитами компиляции (модулями). Каждый модуль может быть скомпилирован отдельно от других, производя на свет файл *.obj формата (универсальный формат), которые потом с помощью линкера подшиваются в один конечный исполняемых файл *.exe.
Так уж повелось, что в целях унификации фирмы-производители компиляторов старались сохранить формат *.obj единым для всех языков (по возможности), что даёт хорошую возможность создавать программы на из юнитов на разных языках программирования. Например модуль на чистопородном ASM можно было сшить в программу на чистопородном C.
Обратная совместимость с этой концепцией ввела в язык C++ некие "странные" на первый взгляд вещи.

*.obj файл исторически устроен сравнительно просто: в нём есть изолированные блоки откомпилированного уже машинного кода и данных, которые сдобрены "метками" - мнемоническими обозначениями, указывающими куда-нибудь внутрь сего дела. Причем в *.obj файле принципиально неизместно чем именно является метка - адресом глобальной переменной, или ф-ии - даже для линкера это непринципиально.

Со старыми языками всё это работало без проблем - экспортные ф-ии и переменные получали совпадающую со своим программным именем метку в *.obj файле и дальше всё шло как по маслу.

А вот в C++ дядя Страуструп ввел такую фичу, как перегруженные ф-ии. Это такие звери, которые хотя и называются в программе одинаково, но имеют разный набор параметров, а следовательно разные тела, наполнение и содержание.
И вот чтобы эту концепцию протянуть через *.obj файлы без конфликта меток пришлось ввести т.н. name mangling. С помощью этого механизма имена переменных и ф-ий в *.obj файлах дополняются специальными длинными абреввиатурами, чтобы исключить конфликт имен конечных перегруженных ф-ий.
Проблема в том, что этот механизм срабатывает всегда и объявив void some(); ты в *.obj файле получить можешь имя для ф-ии вроде _some_v_f. Чтобы нормально спрягать код на C++ с C или ASM, где name mangling отсутствует, введено extern "C", которое отключает сей механизм у экспортируемых или импортируемых имен переменных/ф-ий. Логично, что extern "C" ф-ии не могут быть перегружены.
Так понятно? =)

#5
15:28, 26 окт 2006

Всем большое спасибо!

ПрограммированиеФорумОбщее

Тема в архиве.