2017-04-06 33 views
0

CコードからいくつかのC++関数を呼び出したいと思います。プロジェクトには、main.ccgal_kernel.cppcgal_kernel.hという3つのファイルがあります。CコードからC++関数を呼び出す際の問題

コンパイル時にコンパイルエラーが発生します。

ここに3つのファイルがあります。

cgal_kernel.h

typedef enum{ 
    LEFT_TURN, 
    COLLINEAR, 
    RIGHT_TURN 
} Orientation; 

/* Given points p,q,r determine if the link p-q-r is a left turn, right-turn or collinear 
*/ 
extern Orientation orientation_2 (double px, double py, double qx, double qy, double rx, double ry); 

cgal_kernel.cpp

#include "cgal_kernel.h" 

extern "C" Orientation orientation_2 (double px, double py, double qx, double qy, double rx, double ry) 
{ 
    return LEFT_TURN ; 

} 

main.c

#include <stdio.h> 
#include "cgal_kernel.h" 

int main(void) 
{ 
    double px = 0.0; 
    double py = 0.0; 

    double qx = 0.0; 
    double qy = 1.0; 

    double rx = 1.0; 
    double ry = 1.0; 

    Orientation test= orientation_2 (px, py, qx, qy, rx, ry); 

    printf("Answer is %d\n", test); 
    return 0; 
} 

私はcgal_kernel.cppが彼らの外国機能インターフェイスを介して他の言語から使用する共有ライブラリファイルにコンパイルしたいですs。 bashスクリプト内に格納さ

私のコンパイル手順は、私は上記のビルドスクリプトを実行した後、以下のコンパイルエラーを取得

export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH 
set -ex # Display compilation process. 

rm -f *~ *.o *.so 
g++ -c -Wall -Werror -fPIC cgal_kernel.cpp # Convert to object file 
g++ -shared cgal_kernel.o -o libcgal_kernel.so  
gcc -g -Wall main.c -o main -I. -L. -lcgal_kernel 

です。

+ rm -f *~ *.o *.so 
+ g++ -c -Wall -Werror -fPIC cgal_kernel.cpp 
In file included from cgal_kernel.cpp:1:0: 
cgal_kernel.h: In function ‘Orientation orientation_2(double, double, double, double, double, double)’: 
cgal_kernel.h:17:20: error: previous declaration of ‘Orientation orientation_2(double, double, double, double, double, double)’ with ‘C++’ linkage 
extern Orientation orientation_2 (double px, double py, double qx, double qy, double rx, double ry); 
        ^
cgal_kernel.cpp:3:103: error: conflicts with new declaration with ‘C’ linkage 
extern "C" Orientation orientation_2 (double px, double py, double qx, double qy, double rx, double ry) 

ここで私は間違っていますか?私はその後、私は

+ rm -f *~ cgal_kernel.o libcgal_kernel.so 
+ g++ -c -Wall -Werror -fPIC cgal_kernel.cpp 
+ g++ -shared cgal_kernel.o -o libcgal_kernel.so 
+ gcc -g -Wall main.c -o main -I. -L. -lcgal_kernel 
/tmp/cclw7kGD.o: In function `main': 
/home/gaurish/Dropbox/MyWiki/research_projects/MiCha/main.c:15: undefined reference to `orientation_2' 
collect2: error: ld returned 1 exit status 

は、それは私がC++関数がCコードから呼び出されるかについて、いくつかの基本的ミスを作ってい思わエラーが出るが、私は、関数のシグネチャで、cgal_kernel.cppファイルから"C"を削除しようとしましたそれを理解するように見えることはできません!


EDIT: 私は次のエラーを取得するの両方cgal_kernel.hcgal_kernel.cppファイル内の関数のシグネチャにextern "C"を追加する場合:

+ rm -f *~ cgal_kernel.o libcgal_kernel.so 
+ g++ -c -Wall -Werror -fPIC cgal_kernel.cpp 
+ g++ -shared cgal_kernel.o -o libcgal_kernel.so 
+ gcc -g -Wall main.c -o main -I. -L. -lcgal_kernel 
In file included from main.c:2:0: 
cgal_kernel.h:17:8: error: expected identifier or ‘(’ before string constant 
extern "C" Orientation orientation_2 (double px, double py, double qx, double qy, double rx, double ry); 
     ^
main.c: In function ‘main’: 
main.c:15:3: warning: implicit declaration of function ‘orientation_2’ [-Wimplicit-function-declaration] 
    Orientation test= orientation_2 (px, py, qx, qy, rx, ry); 
^
+5

extern "C"は定義ではなく、定義でなければなりません(私はそれが両方ともにあると思います) – Justin

+2

@Justinそしてあなたは '#if'またはマクロを必要とします。 Cは 'extern" C "'を持っていないので、C++環境です。 –

+0

@Justin編集をご覧ください。私はまだヘッダーファイルに 'extern" C "'を追加することでエラーが発生します – smilingbuddha

答えて

1

CからC++コードを呼び出すための最も簡単な方法がありますこの形式の有効なC/C++ヘッダーファイルを書き込む:

// header guard 
#ifdef __cplusplus 
extern "C" { 
// alternatively, you could have separate C and C++ headers and have 
// the extern "C" before each function in your C++ header 
#endif 

// Valid C header 

#ifdef __cplusplus 
} 
#endif 

そして、Cからそれを使うだけです。C++では、関数を通常と同じように定義します。ご例えば

cgal_kernel.h

#ifdef __cplusplus 
extern "C" { 
#endif 

typedef enum{ 
    LEFT_TURN, 
    COLLINEAR, 
    RIGHT_TURN 
} Orientation; 

/* Given points p,q,r determine if the link p-q-r is a left turn, right-turn or collinear 
*/ 
Orientation orientation_2 (double px, double py, double qx, double qy, double rx, double ry); 

#ifdef __cplusplus 
} 
#endif 

cgal_kernel。注

#include "cgal_kernel.h" 

Orientation orientation_2(double px, double py, double qx, double qy, double rx, double ry) 
{ 
    return LEFT_TURN ; 
} 

cppのあなたの主なファイルはCおよびC++コードを混合する際に、我々はHow to mix C and C++

1

から読み取ることができるように、C++ファイルであるC++の端にあることをextern "C"必要があることを覚えているが、あるべきであることC末端のINVALID SYNTAXです。コードとを混合したときので、一般的に、私はマクロを使用します。

#ifdef __cplusplus 
#define EXTERN_C extern "C" 
#else 
#define EXTERN_C 
#endif 

その後、相互にアクセスできる必要があります任意の関数のすべての宣言にEXTERN_Cを使用しています。つまり、Cコンパイラには見えませんが、C++コンパイラによる名前の変更は避けてください。

関連する問題