2016-08-30 18 views
1

私はにopencv C++ライブラリと別のライブラリを使用しようとしています。だから私は、私は.cCライブラリの.hCからのC++構造体の初期化

typedef struct { 
    cv::FileStorage fs; 
    cv::Mat mat; 
} myCPPStruct; 

#ifdef __cplusplus 
extern "C" { 
#endif 

typedef struct {  
    myCPPStruct * mycppstruct;  
} myCStruct; 

void initialize_myCPPStruct(myCPPStruct * mycppstruct); 

#ifdef __cplusplus 
} 
#endif 

に追加した.hppファイル構造を定義したmyCStructの初期化子としてやや.cppファイルで定義されているinitialize_myCPPStructを呼び出してファイル:

void initialize_myCPPStruct(myCPPStruct * mycppstruct){ 
    mycppstruct = {}; 
    mycppstruct->fs = cv::FileStorage("file.txt", cv::FileStorage::READ); 
    mycppstruct->mat = cv::Mat(3,3,CV_8UC3); 
} 

しかし、それはmycppstruct->fsに値を割り当てようとしたら、それはセグメンテーションフォールトを取得します。私はCにはメモリ割り当てが存在しないためであると仮定し、私はそれがvoid *としてcv:FileStorageを解析することができないとしても動作しません

std::memset(stitcher->fs,0,sizeof(cv::FileStorage));

を試してみました。

この機能を使用するには廃止予定のC OpenCVライブラリを使用する必要がありますか?

編集 - 編集の詳細。 C LIB用

、私は.hファイルに__cplusplus警備員を追加することを確認をしながら、私はg++を使用してC++の機能や構造を追加したすべてのファイル.c-cオプションですなわちリンクせずに)再コンパイルします。 C++コードのない.cファイルはすべて、すでに.oのファイルがgccでコンパイルされています。私はg++でプログラム全体をコンパイルし、関連するライブラリファイルを確実にインクルードします。コンパイラエラーはありません。

+1

? –

+0

@TorbjörnUm、g ++とリンクせずにコンパイルしますか?ここの問題は、コンパイルされていません –

+0

@Torbjörnなぜdownvote?質問はコンパイラの問題ではありません –

答えて

2

構造自体は作成されていないようです。
あなたはこれを試みる場合があります(または類似した何か):

myCPPStruct* initialize_myCPPStruct() 
{ 
    myCPPStruct* result; 
    result = new myCPPStruct(); 
    result->fs = cv::FileStorage("file.txt", cv::FileStorage::READ); 
    result->mat = cv::Mat(3,3,CV_8UC3); 
    return (result); 
} 
+0

さて、単にmyCPPStructを 'new myCPPStruct()'で初期化するのは問題でした。これは私が実際に試みたと思っていたので変です。また、構造体を関数自体に渡すことなく、単純に初期化された構造体を返すように、自分の関数を自分のものとしてリファクタリングしました。 –

2

まず、私は私を混乱させる文を指摘してみましょう。

C

にはメモリ割り当てが存在しないはい、があります。 malloc機能を見てください。

char *my_allocated_string = malloc(sizeof(char) * 42); 

ここであなたは、あなたのサイズ今42

の文字の配列を割り当てられてきた、あると見てい:あなたはC.あなたに構造体を割り当てる方法はありませんmycppstruct = {};

を電話する必要があります... malloc()

my_struct *s = malloc(sizeof(my_struct)); 
s->fs = 42; 

完了しました。気分が良い。


まず、C++コードの周りにラッパーを作成する必要があります。どうして ?

int my_func(int); 
int my_func(char); 

これはCで有効です++:C++は、与えられた関数の複数の定義を可能にするので(またシンボルを呼び出します)。しかし、それについて考えると、コンパイラは同じ名前の2つの関数を存在させることができますか?そうではありません。 2つの異なる名前を作成する関数を評価するときは、manglingという名前のテクニックを使用します。 Manglingは、すべての関数とメソッドで使用されます。単一の機能に関するイベント。

Cは、同じ名前の複数の関数を作成することはできません。それ以外の場合は、の機能が既に実装されているエラーが発生します。

int my_func(int); 

と表示されます。マングリングはありません。

両方の言語が相互作用するようにするには、Cコンパイラが理解できる記号を参照する必要があります。 Cソースファイルからmy_funcを呼び出すと、Cコンパイラはmy_funcシンボルを検索します。 C++はmy_funcシンボルを_ZN9myfuncEのようなものに変更するので、連結は失敗します。だからこそ、C++コンパイラにではなく、という関数にmanglingを使用して、Cに公開する必要があります。そのため、extern "C" { }が必要です。

Feeww、これまでのところは良い...

今、あなたはextern "C"ブロックにあなたのCのAPIを組み込む必要があります:my_c_api.h

my_c_api.cpp

void my_func(int); 
void my_func(char); 

#include "my_c_api.h" 

extern "C" void my_func_i(int i) { my_func(i); } 
extern "C" void my_func_c(char c) { my_func(c); } 

あなたのC++を作成するためにコンパイルします。ブラジャー。

Cコンパイルパイプラインでは、新しいC++ライブラリおよびヘッダーファイルにリンクします。次に:

#include "<path_to_my_c_api.h>" 

void c(int i,char s) 
{ 
    my_func_i(i); 
    my_func_c(c); 
} 

CコンパイラでC++コードをコンパイルすることはできません。あなたはte C++コードを独立してコンパイルする必要があります。あなたの関数ポインタを渡しているため、また、

mycppstruct = {}; 

myCPPStruct = malloc(sizeof(myCPPStruct)); 

は、上記の行の代わりに使用します:あなたはあなたの構造のためのメモリを割り当てる必要が

More on ISO CPP.

2

ポインタをポインタに渡す必要がある場合は、メモリを内部的に割り当てるか、割り当ては返されません。

void initialize_myCPPStruct(myCPPStruct** mycppstruct){ 
     if (mycppstruct == NULL) { 
    //Abort as no address of the pointer to allocate passed 
      return; 
     } 
     *myCPPStruct = malloc(sizeof(myCPPStruct)); 
     (*mycppstruct)->fs = cv::FileStorage("file.txt", cv::FileStorage::READ); 
     (*mycppstruct)->mat = cv::Mat(3,3,CV_8UC3); 
    } 

それともに上記を変えることができる:あなたのCコンパイラは、C++のコードを処理することを期待するにはどうすればよい

関連する問題