Связывание C и заголовки C ++ - PullRequest
0 голосов
/ 11 января 2012

Я хочу использовать некоторые классы c ++ в разделяемой библиотеке с C-связью. И у меня возникли следующие проблемы.

Если

#include <iostream>
extern "C"
{
 void f(){}
}

Успешно компилирует и связывает, но f () не может быть найден в полученной библиотеке.

If

extern "C"
{
#include <iostream>
 void f(){}
}

Я получил много ошибок компилятора (просто не знаю, как правильно перевести их на английский, что-то о шаблоне с C-связью) при каждом появлении ключевого слова C ++ "template" в iostream и включенных заголовках.

Что должно быть сделано?

Ответы [ 3 ]

4 голосов
/ 11 января 2012

Первый вариант правильный. Только вещи, которые даже существуют в C, могут быть объявлены в блоке extern "C", и шаблоны и классы определенно не относятся к этой категории. Вам нужно только убедиться, что ваша функция также объявлена ​​как extern "C" в заголовке, если вы используете C ++ - компилятор. Это часто достигается написанием

#ifdef __cplusplus
// C++ declarations (for example classes or functions that have C++ objects
//                   as parameters)

extern "C"
{
#endif

// C declarations (for example your function f)

#ifdef __cplusplus
}
#endif

в шапке.

2 голосов
/ 11 января 2012

Первое правильно; системные заголовки (и большинство других заголовков) могут быть включены только в глобальную область, вне каких-либо пространств имен, классов, функции или блоки спецификации связи. Есть вероятные вещи в <iostream>, что было бы недопустимо в extern "C", и даже если не было, название искажения для extern "C" почти наверняка отличается от C ++, и сама библиотека была скомпилирована как extern "C++".

Как вы определили f? Это может быть похожая проблема: если источник файл скомпилирует его как extern "C++" функцию, тогда имя будет искажено иначе, чем это было в клиентских файлах, которые скомпилировали его extern "C" функция.

Общая политика здесь заключается в обработке заголовков и функции определения / декларации так же, как вы обычно делаете, за исключением того, что вы гарантируете, что заголовок может быть включен как в C, так и в C ++, e.g.:

#if __cplusplus
extern "C" {
#endif
void f();
//  Other `extern "C"` functions...
#if __cplusplus
}
#endif

Затем включите этот заголовок во все файлы, где используется функция f(), и в файле, где он определен.

0 голосов
/ 11 января 2012

Используйте __declspec для экспорта функций, классов и т. Д ... Также: http://msdn.microsoft.com/en-us/library/a90k134d(v=vs.80).aspx

И это очень хорошо: http://www.flounder.com/ultimateheaderfile.htm

...