Вызвать функцию C из кода С++

У меня есть функция C, которую я бы хотел вызвать из С++. Я не мог использовать подход "extern "C" void foo()", потому что функция C не была скомпилирована с использованием g++. Но он компилируется с использованием gcc. Любые идеи о том, как вызвать функцию из С++?

57
задан 31 мая '13 в 9:27
источник поделиться
3 ответов

Скомпилируйте код C следующим образом:

gcc -c -o somecode.o somecode.c

Затем код С++ выглядит следующим образом:

g++ -c -o othercode.o othercode.cpp

Затем свяжите их вместе с компоновщиком С++:

g++ -o yourprogram somecode.o othercode.o

Вы также должны сообщить компилятору С++, когда заголовок C появляется, когда вы включаете объявление для функции C. Итак, othercode.cpp начинается с:

extern "C" {
#include "somecode.h"
}

somecode.h должен содержать что-то вроде:

 #ifndef SOMECODE_H_
 #define SOMECODE_H_

 void foo();

 #endif

<ч/" > (Я использовал gcc в этом примере, но принцип тот же для любого компилятора. Создайте отдельно как C и С++ соответственно, затем соедините его вместе.)

78
ответ дан 31 мая '13 в 9:29
источник

Позвольте мне собрать фрагменты из других ответов и комментариев, чтобы дать вам пример с чисто разделенным кодом C и С++:

Часть C:

foo.h

#ifndef FOO_H
#define FOO_H

void foo(void);

#endif 

foo.c

#include "foo.h"

void foo(void)
{
    /* ... */
}

Скомпилируйте это с помощью gcc -c -o foo.o foo.c.

Часть С++:

bar.cpp

extern "C" {
  #include "foo.h" //a C header, so wrap it in extern "C" 
}

void bar() {
  foo();
}

Скомпилируйте это с помощью g++ -c -o bar.o bar.cpp

И затем соедините все это вместе:

g++ -o myfoobar foo.o bar.o

Обоснование: Код C должен быть простым кодом C, no #ifdef для "возможно, когда-нибудь я назову это с другого языка". Если какой-то программист на С++ называет ваши C-функции, это его проблема, как это сделать, а не ваша. И если вы программист на С++, то заголовок C может быть не вашим, и вы не должны его изменять, поэтому обработка неподключенных имен функций (т.е. extern "C") принадлежит вашему коду С++.

Конечно, вы можете написать себе удобный заголовок С++, который ничего не делает, кроме как обернуть заголовок C в объявление extern "C".

35
ответ дан 31 мая '13 в 11:05
источник

Я согласен с Проф. Falken answer, но после комментария Арне Мерца я хочу привести полный пример (самая важная часть - #ifdef __cplusplus):

somecode.h

#ifndef H_SOMECODE
#define H_SOMECODE

#ifdef __cplusplus
extern "C" {
#endif

void foo(void);

#ifdef __cplusplus
}
#endif

#endif /* H_SOMECODE */

somecode.c

#include "somecode.h"

void foo(void)
{
    /* ... */
}

othercode.hpp

#ifndef HPP_OTHERCODE
#define HPP_OTHERCODE

void bar();

#endif /* HPP_OTHERCODE */

othercode.cpp

#include "othercode.hpp"
#include "somecode.h"

void bar()
{
    foo(); // call C function
    // ...
}

Затем вы следуете инструкциям профессора Фалькена для компиляции и ссылки.

Это работает, потому что при компиляции с gcc макрос __cplusplus не определен, поэтому заголовок somecode.h, включенный в somecode.c, подобен этому после предварительной обработки:

void foo(void);

и при компиляции с g++ определяется __cplusplus, поэтому заголовок, включенный в othercode.cpp, теперь выглядит следующим образом:

extern "C" {

void foo(void);

}
16
ответ дан 31 мая '13 в 10:30
источник

Другие вопросы по меткам или Задайте вопрос