Связь с Clion не удалась

У меня есть файл заголовка

// Creates a new graph with n vertices and no edges
graph_t *graph_create(int n);

Файл .c

graph_t *graph_create(int n)
{
    graph_t *g;
    int     i;

    //g = malloc(sizeof(graph_t));
    g->V = n;
    g->E = 0; 

    return g;
}

Так выглядит мой CMakeLists.txt

cmake_minimum_required(VERSION 3.3)
project(Thesis)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

set(SOURCE_FILES main.cpp graph.h graph.c shared.h)
add_executable(Thesis ${SOURCE_FILES})

Я вызываю graph_t *g = graph_create(15); из main.cpp и получаю следующую ошибку о том, что метод не определен:

"C: \ Program Files (x86) \ JetBrains \ CLion 1.2.4 \ bin \ cmake \ bin \ cmake.exe" - build C: \ Users \ Shiro.CLion12 \ system \ cmake \ generated \ 6e6ca233 \ 6e6ca233 \ Debug --target Thesis - -j 8 Сканирование зависимостей целевой Thesis [66%] Построение CXX-объекта CMakeFiles / Thesis.dir / main.cpp.obj [66%] Построение C-объекта CMakeFiles / Thesis.dir / graph.c.obj [100%] Связывание исполняемого файла CXX Thesis.exe CMakeFiles \ Thesis.dir / objects.a (main.cpp.obj): в функции main': C:/Users/Shiro/ClionProjects/Thesis/main.cpp:7: undefined reference tograph_create (int) 'collect2.exe: error: ld вернул 1 статус выхода CMakeFiles \ Thesis.dir \ build.make: 121: рецепт цели 'Thesis.exe' не удалось mingw32-make.exe [3]: [Thesis.exe] Ошибка 1 CMakeFiles \ Makefile2: 66: рецепт цели 'CMakeFiles / Thesis.dir / all' сбой CMakeFiles \ Makefile2: 78: рецепт для целевого файла 'CMakeFiles / Thesis.dir / rule' сбой Makefile: 117: рецепт для целевого 'Thesis' сбой mingw32-make.exe [2]: [CMakeFiles / Thesis.dir / all] Ошибка 2 mingw32-make.exe [1]: [CMakeFiles / Thesis.dir / rule] Ошибка 2 mingw32-make.exe: [Thesis] Er рор 2

Что я делаю неправильно ?


person dimitris93    schedule 22.02.2016    source источник
comment
См. также этот ответ   -  person Niall    schedule 22.02.2016
comment
@Niall Спасибо, это тоже помогло   -  person dimitris93    schedule 22.02.2016


Ответы (1)


Предполагая, что функция определена в исходном файле graph.c C, проблема связана с искажением имени .

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

extern "C" graph_t *graph_create(int n);

Однако с этим есть проблема: компилятор C не узнает, что вы имеете в виду под extern "C", и будет жаловаться. Для этого вам нужно использовать условную компиляцию с использованием препроцессора и проверить, используется ли файл заголовка компилятором C ++ или C. Это делается путем проверки существования макроса __cplusplus:

#ifdef __cplusplus
extern "C"
#endif
graph_t *graph_create(int n);

Если у вас несколько функций, поместите их в блок, заключенный в фигурные скобки:

#ifdef __cplusplus
extern "C" {
#endif

graph_t *graph_create(int n);
// More functions here...

#ifdef __cplusplus
}  // End of extern "C" block
#endif
person Some programmer dude    schedule 22.02.2016
comment
Хм, я ожидал ответа в строках, вам нужно изменить настройки X. Но это определенно сработало. Итак, мне действительно нужно добавить #ifdef __cplusplus extern "C" #endif в каждый файл заголовка? Будет ли это создавать какие-либо проблемы с совместимостью? Я имею в виду, что люди используют это чистое решение? Я понимаю, что это проблема с разными компиляторами C и C ++, а не с самой IDE, поэтому это решение используется во всех программах, использующих C и C ++ одновременно? - person dimitris93; 22.02.2016
comment
@Shiro Если вы посмотрите практически любую библиотеку C, которую найдете в Интернете, вы увидите это. Это единственный способ обойти проблему искажения имен. И это полностью безопасно и лишь незначительно повлияет на время компиляции (как не измеримо). - person Some programmer dude; 22.02.2016
comment
Что ж, это отличные новости, и спасибо за удивительное объяснение в вашем ответе искалеченных имен. - person dimitris93; 22.02.2016
comment
Следует ли помещать в эти скобки весь заголовочный файл? или только функции? есть реальная разница? - person dimitris93; 22.02.2016
comment
@Shiro Это не имеет значения, будут затронуты только функции и их прототипы. Я видел оба стиля. - person Some programmer dude; 22.02.2016