Вопрос по visual-studio-2008, c++, extern, c – extern C не может быть использован на уровне класса?

9

Просто хочу подтвердить, что в среде Windows, проекте VSTS 2008 + C ++, мы могли только применять extern C к уровню функций, но не могли применяться к уровню класса (чтобы все функции-члены из класса использовали искажение имени языка C)? Я пробовал несколько способов, но всегда ошибка компиляции.

заранее спасибо, Джордж

@ephemient, я хочу подтвердить, что функции-члены класса C ++ не могут быть экспортированы с помощью extern C, как мы можем экспортировать функцию-член? Нужно определить глобальную функцию-обертку и экспортировать глобальную функцию-обертку? George2
@ George2: Вопрос, который задают люди: почему вы хотите экспортировать функции класса с C-связью? Независимо от того, сколько печатать это может занять, в чем смысл этого. Обычно люди экспортируют функции с C-связью, чтобы сделать их связанными и вызываемыми из C-кода. Но функции классов по своей природе не могут быть вызваны из C-кода. Даже если вам удастся каким-либо образом экспортировать их с помощью C-linkage, вы все равно не сможете их вызвать. Таким образом, вопрос заключается в следующем: какой смысл экспортировать в этом случае? AnT
Поскольку C не имеет никакого понятия о классах или функциях-членах, нет смысла давать функциям-членам прямую связь уровня C. Что ты действительно хочешь? ephemient
Я хочу сохранить свою типизацию и быть более гибким в своем коде, то есть я определяю параметр extern C на уровне класса, после чего все последующие добавления функций-членов в класс автоматически & quot; наследуют & quot; этот вариант. Есть комментарии или идеи? George2
С какой целью? Чтобы иметь возможность вызывать функции-члены из C? (Невозможно без некоторого косвенного обращения.) Иметь непонятные имена в объектах? (Невозможно, столкновения пространства имен.) ephemient

Ваш Ответ

4   ответа
4

что нет. Но если вы хотите передать объект C ++ функциям C, вы можете обратиться к этой ссылке:http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html#faq-32.8

@ephemient: _
Я полагаю, что ysth пытался предоставить контрпример, но я этого не вижу: C identifier & quot;" --> symbol "& Quot; для ссылки.
@ephemient, что вы подразумеваете под "идентификатором C"?" --> symbol "& Quot; для связи. & quot ;? Не могли бы вы сказать другими словами, пожалуйста? George2
Вы можете определить & quot; искажение в стиле C & quot; как "без искажения". Упорядочивание имен используется для C ++ как способ заставить компоновщики поддельной поддержки перегруженных функций. Поскольку C не имеет перегруженных функций, вам не нужно беспокоиться об этом. Однако некоторые архитектуры добавляют подчеркивание к имени переменной; так что "х" в источнике станет & quot; _x & quot; в двоичном Я не видел этого, но возможно, что компилятор C мог бы использовать искажение имен C ++ в качестве способа перехвата ошибок типа во время соединения, даже без перегрузки. Но время ссылки слишком поздно, чтобы быть полезным.
Нет, мой вопрос заключается в том, можем ли мы применить extern C на уровне класса, чтобы все функции в классе автоматически имели искажение имен в стиле C? George2
5

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

Clarifying: Структуры и объединения находятся в C, но не имеют функций-членов, поэтому их функции-члены в C ++ нельзя экспортировать в стиле c (и определения структуры и объединения не нужно экспортировать, поскольку они уже находятся в заголовке)

Спасибо Тодд, если функции-члены класса не могут быть экспортированы с использованием extern C, как мы можем экспортировать функцию-член? Нужно определить глобальную функцию-обертку и экспортировать глобальную функцию-обертку? George2
Привет, Тодд, пожалуйста, поправь меня, если я ошибаюсь, структуры и объединения являются функцией C, и мы не можем добавить extern C в struct и union, а не в пространство имен? George2
12

extern "C" к функции-члену через очень запутанный (но полностью законный) хак:

extern "C" typedef int bar_t(int x);

struct foo {
     bar_t bar; // yes, this declares a nonstatic member function!
};

int foo::bar(int x) { return x; } // definition

Это возможно в соответствии с ISO C ++ 03 9.3 [class.mfct] / 9:

a member function can be declared (but not defined) using a typedef for a function type. The resulting member function has exactly the same type as it would have if the function declarator were provided explicitly, see 8.3.5.

Однако из-за ISO C ++ 03 7.5 [dcl.link] / 4 это вам ничего не даст.

A C language linkage is ignored for the names of class members and the member function type of class member functions.

Да, это малоизвестная особенность :) Вы также можете включить конечный квалификатор const в объявление typedef-name, как вtypedef int bar_t(int) const; в этом случае это имя typedef будет использоваться только для объявления функций-членов, но не для обычных функций.
2

extern "C" принудительная связь в стиле C Его нельзя использовать с классами AFAIK.

Кроме того, не может быть использован со структурой? George2
Я считаю, что это не может быть использовано с чем-то, что имеет методы. Он должен работать со структурами, которые содержат только элементы данных, и пока ни один из элементов данных не требует построения или уничтожения. У меня нет доступа к среде Windows, поэтому я снимаю с бедра :) Я полагаю, что это extern "C" не будет работать с чем-либо, что требует искажения имени, так что функции, которые переопределены, вероятно, тоже отсутствуют. В зависимости от того, что вы пытаетесь сделать, может быть, есть лучший способ сделать это.
C-линкеры не действительно "искажают имена" в традиционном смысле. Самое большее, они будут добавлять префикс к имени. C ++ "искажение имен" кодирует информацию о типе в символ компоновщика, чтобы сделать возможной перегрузку функций и другие псевдонимы. "внешний C" лучше всего описывать как отключение искажения имени в C ++. В результате все, что делает возможным кодирование типов, больше невозможно. Следовательно, нет перегрузок, нет методов, нет конструктора / деструкторов и т. Д. Проверьтеen.wikipedia.org/wiki/Name_mangling для хорошего описания.
1. "Я предполагаю, что внешний" C " не будет работать с чем-либо, что требует искажения имени, так что функции, которые переопределены, вероятно, тоже отсутствуют. & quot; - extern C используется для принудительного искажения имени в стиле C, но почему вы говорите: extern "C" не будет работать с чем-либо, что требует искажения имени? 2. «пока ни один из элементов данных не требует создания или уничтожения»; - требуется конструкция или уничтожение означает, что типы данных не POD, которые не имеют ctor / dtor? George2

Похожие вопросы