У меня есть функция C, которую я бы хотел вызвать из C++. Я не мог использовать «extern "C" void foo()
», потому что функция C не скомпилировалась с помощью g ++. Но он компилируется с использованием gcc. Любые идеи, как вызвать функцию из C++?Вызов функции C из кода C++
ответ
Скомпилировать C так:
gcc -c -o somecode.o somecode.c
Тогда код C++, как это:
g++ -c -o othercode.o othercode.cpp
Затем связать их вместе с С ++ линкера:
g++ -o yourprogram somecode.o othercode.o
You также нужно сообщить компилятору C++, когда заголовок C появляется, когда вы включаете объявление для функции C. Так othercode.cpp
начинается с:
extern "C" {
#include "somecode.h"
}
somecode.h
должен содержать что-то вроде:.
#ifndef SOMECODE_H_
#define SOMECODE_H_
void foo();
#endif
(я использовал GCC в этом примере, но принцип одинаков для любого компилятора Построить отдельно C и C++, соответственно, затем свяжите его вместе.)
Я не хочу использовать nipick, но этот последний код - это * Объявление *, а не * определение *. Однако, поскольку 'somecode.h', возможно, будет заголовком C, который он мог бы использовать и в компиляции C, запись' extern 'C "' в заголовке нарушила бы компиляцию C.Вместо этого он должен обернуть «extern» C «вокруг C-заголовка include в исходный файл C++. –
@ Арне Хорошие очки. Некоторые люди просматривают некоторые C++ в своих C, завершая 'extern 'C" 'в заголовке с помощью [' #ifdef __cplusplus'] (http://stackoverflow.com/questions/3789340/combining-c-and-c-how -does-IFDEF-cplusplus работа). – unwind
@ Арне См. Мой ответ ниже. расслабьтесь Как видите, я один из них;) –
Я согласен с Prof. Falken's answer, но после комментария Арне Мерца я хочу gi ве полный пример (наиболее важной частью является #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
// ...
}
Тогда вы будете следовать инструкции профессора Falken для компиляции и компоновки.
Это работает, потому что при компиляции с gcc
, макрос __cplusplus
не определен, поэтому заголовок somecode.h
включен в somecode.c
, как это после предварительной обработки:
void foo(void);
и при компиляции с g++
, то __cplusplus
является и поэтому заголовок, включенный в othercode.cpp
, теперь выглядит следующим образом:
extern "C" {
void foo(void);
}
thb, мне не нравится '#ifdef __cplusplus' в коде C. Код C - это более низкий уровень, и ему не нужно беспокоиться о том, может ли он когда-нибудь вызываться из кода на C++. Imo, что '# ifdef' используется только в коде C++, если вы хотите предоставить заголовок связывания C для библиотеки, написанной на C++, а не наоборот. –
@ArneMertz, тем не менее, это хорошее определение, о котором нужно знать. –
@ Prof.Falken, конечно, но это определение, предназначенное для обеспечения «нисходящей» совместимости кода C++, а не кода C. –
Позвольте мне собрать биты и куски из других ответов и комментариев, чтобы дать вам пример с чисто отделенной 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
.
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, #ifdef
s для «возможно, когда-нибудь я позвоню на другом языке». Если какой-либо программист на C++ называет ваши функции C, то его проблема, как это сделать, а не ваша. И если вы программист на C++, то заголовок C может не быть вашим, и вы не должны его изменять, поэтому обработка неподключенных имен функций (то есть extern "C"
) принадлежит вашему коду C++.
Возможно, вы можете написать себе удобный заголовок C++, который ничего не делает, кроме как обернуть заголовок C в объявлении extern "C"
.
Кажется законным. +1 для обоснования –
Большое спасибо, это сработало отлично! – Dangila
+1 для обоснования тоже –
Этот ответ вдохновлен случаем, когда обоснование Арне было правильным. Поставщик написал библиотеку, которая когда-то поддерживала C и C++; Однако, последняя версия поддерживается только C. Следующие рудиментарные директивы остаются в коде были вводить в заблуждение:
#ifdef __cplusplus
extern "C" {
#endif
Это стоило мне несколько часов, пытаясь скомпилировать в C++. Просто вызов C из C++ был намного проще.
Конвенция ifdef __cplusplus нарушает принцип единой ответственности.Код с помощью этой конвенции пытается сделать две вещи сразу:
- (1) выполняют функцию в C - и -
- (2) выполняют ту же функцию в C++
Это как попытка написать как на американском, так и на британском английском языке одновременно. Это излишне бросает #ifdef __thequeensenglish гаечный ключ #elif __yankeeengrench гаечный ключ #else бесполезный инструмент, который делает код труднее читать #endif в код.
Для простого кода и небольших библиотек может работать соглашение ifdef __cplusplus; однако для сложных библиотек лучше всего выбрать один или другой язык и придерживаться его. Поддержка одного из языков потребует меньшего обслуживания, чем для поддержки обоих.
Это запись изменений, которые я сделал для кода Арне, чтобы его можно было скомпилировать на Ubuntu Linux.
foo.h:
#ifndef FOO_H
#define FOO_H
void foo(void);
#endif
foo.c
#include "foo.h"
#include <stdio.h>
void foo(void)
{
// modified to verify the code was called
printf("This Hello World was called in C++ and written in C\n");
}
bar.cpp
extern "C" {
#include "foo.h" //a C header, so wrap it in extern "C"
}
int main() {
foo();
return(0);
}
Makefile
# -*- MakeFile -*-
# dont forget to use tabs, not spaces for indents
# to use simple copy this file in the same directory and type 'make'
myfoobar: bar.o foo.o
g++ -o myfoobar foo.o bar.o
bar.o: bar.cpp
g++ -c -o bar.o bar.cpp
foo.o: foo.c
gcc -c -o foo.o foo.c
- 1. Вызов функции C++ из кода C
- 2. вызов c-кода из C++
- 3. Вызов функции Javascript из кода в C#
- 4. tolua ++ Вызов функции Lua из кода C++
- 5. Вызов функции numpy из C-кода
- 6. Вызов DLL-функции delphi из кода C#
- 7. вызов функции C# из кода aspx
- 8. Вызов кода C# из неуправляемого C++?
- 9. Вызов функции C# из функции C++/CLI
- 10. Вызов кода C из node.js
- 11. Вызов функции C++ из C#
- 12. вызов функции c из C#
- 13. вызов функции C++ из java без изменения кода C++
- 14. вызов метода C++ из кода C
- 15. Вызов функции библиотеки C/C++ из PHP
- 16. Вызов кода C/C++ из кода Fortran 77
- 17. Вызов функции C# из C++ DLL
- 18. Вызов функции C++ из Javascript
- 19. Вызов визуального кода на C++ из C#
- 20. Вызов кода приложения C++ из библиотеки C?
- 21. Вызов метода Objective-C из кода C
- 22. Вызов WCF из кода C
- 23. Вызов кода C из FORTRAN
- 24. Вызов неуправляемого кода из C#
- 25. Вызов кода Java из C
- 26. Вызов кода C++ из MATLAB?
- 27. Вызов функции C++ из Java
- 28. Вызов функции javascript из C++
- 29. Вызов функции Matlab из C++
- 30. Вызов функции Python из C++
Не могли бы вы написать несколько примеров коды и '' г ++ сообщения об ошибках –
@MarkGarcia C и C++ являются разными языками. Да, в C есть вещи, которых нет в C++. Мне надоело объяснять это, поэтому я спросил [Почему я не должен компилировать код C с помощью компилятора C++ или писать код на C++ для компиляции в C?] (Http://stackoverflow.com/questions/16247969/ why-shouldnt-i-compile-c-code-with-ac-or-write-c-code-to-be-compileable-in) – Sebivor
Это может быть обратное. _failed для компиляции с использованием gcc. Но он компилируется отлично, используя g ++ _... из-за 'extern 'C'' –