Включение функций с внешней связью C в библиотеку

Я включил некоторые функции C с внешней связью c в код C++. Например.

// File Y.cpp: 

extern C {  
 void fnA(void) { }  
 void fnB(void* a, void* b) { }  
}

class test {
....
};

// end of file

Файл Y находится в модуле Mod. При сборке библиотеки libMod-O.a для модуля Mod я не вижу включенных функций в блоке extern, если только Y.h не включен в какой-либо другой файл (Mod.cpp) и не используется тест класса. Поэтому, если я не создам объект тестового класса в Mod.cpp, я не вижу внешних функций (fnA, fnB) в libMod-O.a, даже если Y.cpp компилируется во время сборки libMod-O.a. В результате возникает ошибка компоновщика, так как другой модуль использует fnA, fnB.

Я не вижу связи между включенными внешними функциями fnA и fnB и использованием class test в Mod.cpp. Ожидается ли это или есть лучший способ определить это?


person cppcoder    schedule 21.06.2011    source источник
comment
Рекомендуется переместить объявления extern C в файл h. И включайте этот файл h везде, где вы используете эти внешние функции.   -  person George Gaál    schedule 22.06.2011
comment
когда вы говорите «я не вижу включенных функций», вы имеете в виду, что использовали objdump или другой метод для просмотра содержимого архива, или вы просто имеете в виду, что получаете ошибки компоновщика?   -  person dmh2000    schedule 22.06.2011
comment
у вас может возникнуть проблема с порядком ссылок, когда файлы, использующие fnA, идут после ссылки libMod-O.a, но где Mod.cpp с проверкой объекта идет перед libMod-O.a, поэтому файл obj загружается до того, как fnA/fnB понадобится позже. компоновщик gnu по умолчанию является компоновщиком с одним проходом.   -  person dmh2000    schedule 22.06.2011
comment
Нажмите на ссылку, предложенную Тьяго, и узнайте.   -  person karlphillip    schedule 22.06.2011


Ответы (2)


Вы имеете в виду extern "C", конечно.

У вас должно быть четкое разделение между вашим кодом C и вашим кодом C++.

В YourCCode.h:

#ifdef __cplusplus
extern "C" {
#endif

void fnA(void);
void fnB(void* a, void* b);

#ifdef __cplusplus
}
#endif

В YourCCode.c:

void fnA(void) {}
void fnB(void* a, void* b) {}

Убедитесь, что ваш компилятор компилирует YourCCode.c как C, а не как C++.

В вашем коде C++

#include "YourCCode.h"

fnA();
// etc.
person Gnawme    schedule 21.06.2011

у вас может возникнуть проблема с порядком ссылок, когда файлы, использующие fnA, идут после ссылки libMod-O.a, но где Mod.cpp с проверкой объекта идет перед libMod-O.a, поэтому файл obj загружается до того, как fnA/fnB понадобится позже. компоновщик gnu по умолчанию является компоновщиком с одним проходом.

person dmh2000    schedule 21.06.2011
comment
Я не использовал строки или objdump для просмотра символов. Я получил ошибку компоновщика. libMod-O.a также является библиотекой для Mod.cpp. И Y.cpp, и Mod.cpp компилируются в libMod-O.a. В противном случае я не уверен, как создание объекта теста в Mod.cpp решает проблему. - person cppcoder; 22.06.2011
comment
Я просто запустил команду strings и нашел fnA и fnB в libMod-O.a. Но ошибка ссылки все равно возникает, так как в Mod.cpp не используется class test. - person cppcoder; 22.06.2011