Wywołanie funkcji C z kodu C++
Mam funkcję C, którą chciałbym wywołać z C++. Nie mogłem użyć podejścia " extern "C" void foo()
", ponieważ funkcja C nie została skompilowana przy użyciu g++. Ale kompiluje dobrze za pomocą gcc. Jakieś pomysły jak wywołać funkcję z C++?
4 answers
Skompiluj kod C tak:
gcc -c -o somecode.o somecode.c
Następnie kod C++ w następujący sposób:
g++ -c -o othercode.o othercode.cpp
Następnie połącz je razem, za pomocą linkera C++:
g++ -o yourprogram somecode.o othercode.o
Musisz również powiedzieć kompilatorowi C++, że nagłówek C nadchodzi, gdy dołączysz deklarację dla funkcji C. Więc othercode.cpp
zaczyna się od:
extern "C" {
#include "somecode.h"
}
somecode.h
powinno zawierać coś w rodzaju:
#ifndef SOMECODE_H_
#define SOMECODE_H_
void foo();
#endif
(użyłem gcc w tym przykładzie, ale zasada jest taka sama dla każdego kompilatora. Budować osobno jako C i C++, a następnie połączyć je ze sobą.)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-23 12:03:29
Pozwól, że zbiorę fragmenty z innych odpowiedzi i komentarzy, aby dać ci przykład z czystym kodem C i C++:
Część C:
Foo.h :
#ifndef FOO_H
#define FOO_H
void foo(void);
#endif
Foo.c
#include "foo.h"
void foo(void)
{
/* ... */
}
Skompiluj to za pomocą gcc -c -o foo.o foo.c
.
Część C++:
Bar.cpp
extern "C" {
#include "foo.h" //a C header, so wrap it in extern "C"
}
void bar() {
foo();
}
Skompiluj to z g++ -c -o bar.o bar.cpp
A następnie połączyć to wszystko razem:
g++ -o myfoobar foo.o bar.o
Uzasadnienie:
Kod C powinien być zwykłym kodem C, Nie #ifdef
s jak "może kiedyś nazwę To z innego języka". Jeśli jakiś Programista C++ wywoła twoje funkcje C, to jest ich problem JAK to ZROBIĆ, NIE Twój. A jeśli jesteś programistą C++, to nagłówek C może nie być twój i nie powinieneś go zmieniać, więc obsługa niezmieszanych nazw funkcji (np. extern "C"
) należy do Twojego kodu C++.
Możesz oczywiście napisać sobie wygodny nagłówek C++, który nie robi nic poza owijaniem nagłówka C w extern "C"
deklaracja.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-20 04:11:18
Zgadzam się z odpowiedzią Prof. Falkena , ale po komentarzu Arne ' a Mertza chcę podać pełny przykład (najważniejsza część to #ifdef __cplusplus
):
Jakiś kod.h
#ifndef H_SOMECODE
#define H_SOMECODE
#ifdef __cplusplus
extern "C" {
#endif
void foo(void);
#ifdef __cplusplus
}
#endif
#endif /* H_SOMECODE */
Jakiś kod.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
// ...
}
Następnie postępuj zgodnie z instrukcjami Prof. Falkena, aby skompilować i połączyć.
To działa, ponieważ podczas kompilacji z gcc
, makro __cplusplus
nie jest zdefiniowany, więc nagłówek somecode.h
zawarty w somecode.c
jest taki po wstępnym przetworzeniu:
void foo(void);
I przy kompilacji z g++
, wtedy __cplusplus
jest zdefiniowany, a więc nagłówek zawarty w othercode.cpp
jest teraz taki:
extern "C" {
void foo(void);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:44
Ta odpowiedź jest inspirowana przypadkiem, w którym uzasadnienie Arne ' a było poprawne. Jednak najnowsza wersja wspierała tylko C. następujące dyrektywy pozostawione w kodzie były mylące: {]}
#ifdef __cplusplus
extern "C" {
#endif
To kosztowało mnie kilka godzin próby kompilacji w C++. Proste wywołanie C z C++ było znacznie łatwiejsze.
Konwencja ifdef __cplusplus narusza zasadę jednej odpowiedzialności. Kod wykorzystujący ten Konwent próbuje robić dwie rzeczy na raz:
- (1) Wykonaj funkcję w C -- i --
- (2) wykonanie tej samej funkcji w C++
Dla prostego kodu i małych bibliotek ifdef _Konwencja _cplusplus może działać, jednak w przypadku złożonych bibliotek najlepiej wybrać jeden lub drugi język i trzymać się go. Obsługa jednego z języków wymaga mniej konserwacji niż próba obsługi obu języków.
Jest to zapis modyfikacji, które zrobiłem w kodzie Arne ' a, aby go skompilować na 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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-22 03:21:13