1

もともと構造継承で設計された C++ ライブラリから受け取った C プログラム データにアクセスしようとしています。

例:

// C++ data structures
typedef struct _Base
{
public:
    int id;
    wchar_t* name;
} Base;


typedef struct _Struct1 : Base
{
public:
    int valueCount;
} Struct1;


typedef struct _Struct2 : Base
{
public:
    int parentID;
    int amount;
} Struct2;

マッピングのためにCで次のデータ構造を使用してみました。

typedef struct _Base
{
    int id;
    wchar_t* name;
} Base;


typedef struct _Struct1
{
    // Base struct data
    int id;
    wchar_t* name;

    int valueCount;
} Struct1;


typedef struct _Struct2
{
    // Base struct data
    int id;
    wchar_t* name;

    int parentID;
    int amount;
} Struct2;

しかし、データを印刷すると、間違った値が得られたようです。

C++ が継承された構造を内部的に表現する方法についての参照がありませんか?

前もって感謝します!

4

4 に答える 4

3

POD に関する C++11 の規則 ( Aggregate と POD とは何か、それらはどのように/なぜ特別なのか? )と明記する 具体的な基底クラスとデータ メンバーを混在させることはできませんが、実際には、ほとんどのコンパイラで単一の POD 基底クラスを持つことは、そのクラスを最初のメンバーとしてカプセル化することと同じです。

基本構造体をカプセル化する C 構造体を指定してみてください。

typedef struct _Struct1
{
    Base base;
    int valueCount;
} Struct1;

C++ クラスが非 POD の場合 (たとえば、仮想メソッドがある場合)、これは機能しないことに注意してください。

于 2012-05-31T19:18:26.103 に答える
2

C コンパイラをだまして C++ クラスと同じメモリ レイアウトの構造体を生成させることができ、多くの場合はうまくいきますが、これを構築するにはかなり不安定な基盤です。

移植可能な方法は、アクセサー関数を作成することです。として宣言してくださいextern "C"

ヘッダー ファイルの説明的な例 (必ずしもクリーンである必要はありません。Web フォームにコードを記述する際の一般的な注意事項が適用されます :-)):

#ifdef __cplusplus

// C++ declarations go here

class Foo
{
public:
   int bar;
};

// C calling conventions follow

extern "C" {

#else

// Make it so your C code can work with Foo* as an incomplete/not-dereferencable
// type.
typedef void Foo;

#endif

// Declare this in a C++ source file to return fooptr->bar
int foo_get_bar(Foo *fooptr);

#ifdef __cplusplus
} // extern "C"
#endif
于 2012-05-31T19:15:04.227 に答える
1

調査する 1 つの可能性は、定義した構造体は正しいが、コンパイラが使用している配列が一致しないことです。見る:

http://en.wikipedia.org/wiki/Data_structure_alignment

通常、コンパイラ スイッチまたは #pragma ディレクティブを使用してアライメントを設定できます。それについて知るには、コンパイラのドキュメントを読む必要があります。C++ コードの作成者に連絡できない場合は、デバッガーを使用して、受け取った生のメモリを調べて、構造内の異なる値の間のアラインメント/パディングを確認する必要があります。

1 つのプログラムを 64 ビット マシン用にコンパイルし、もう 1 つのプログラムを 32 ビット マシン用にコンパイルすると、この種の問題が発生する可能性があります。または、さまざまなコンパイラの実装が原因である可能性があります。

于 2012-05-31T19:25:57.920 に答える
0

C++ 側からのものを直接使用するのではなく、C++ から C に値を出力するために使用している C++ ライブラリでラッパー レイヤーを使用してみることができます。余分なレイヤーからのオーバーヘッドが重要でない場合、これはうまくいく可能性があります。

C++ クラスのキャストは、メンバーと仮想メソッドのポインターをクラス構造内に保持するため、常に機能するとは限りません。

于 2012-05-31T19:14:54.370 に答える