8

structa を C- として前方宣言することは合法ですか?struct

// api.h
#ifdef __cplusplus
extern "C" {
#endif

    typedef struct handle_tag handle_t;

    handle_t *construct();
    void destruct(handle_t *h);

    void func(handle_t *h);

#ifdef __cplusplus
}
#endif

その後、それを C++-structとして、つまり非 POD 型として定義しますか?

// api.cpp
struct handle_tag {
    void func();
    std::string member;
};

void func(handle_t *h) {
    h->func();
}

handle_t一般的な意図は、C インターフェイスを介して、C++ データ型として内部的に実装された外部からアクセス可能な不透明型を取得することです。

4

2 に答える 2

9

はい、Cコードが構造の「内部」を見る必要がなくhandle_tag、適切なC++構築/破壊がC++コードによって実行される限り、それはうまく機能します(私はそれが目的であると想定していconstructますdestruct)。

C コードが必要とするのは、何らかのデータ構造へのポインターだけです。コンテンツが何であるかはわかりません。そのため、コンテンツは、コンストラクター/デストラクターに依存するデータを含め、好きなものにすることができます。

void *編集: これ、またはそれに類似したメソッド (たとえば、 a を使用して C 部分のオブジェクトのアドレスを に記録するhold) は、C コードを C++ 機能にインターフェースするためのかなり一般的な方法であることを指摘しておく必要があります。

Edit2: 呼び出された C++ コードが例外を C コードに「リーク」しないことが重要です。それは未定義の動作であり、クラッシュ、またはさらに悪いことに、クラッシュしない「奇妙なこと」を引き起こす可能性が非常に高くなります...したがって、コードが例外を引き起こさないことが保証されていない限り(std::stringたとえばbad_alloc、メモリ)、 C++ 側でanfのtry/catchようなコード内でブロックを使用する必要があります。constructfunc

于 2013-07-10T10:54:24.287 に答える
2

そのままでは機能しませんが、コンセプトは問題ありません。関数が定義されている場合は、C コードがそれらを見つけられるように、名前が壊れていないことも確認する必要があります。つまり#include "api.h"、api.cpp ファイルの上に追加する必要があります。

于 2013-07-10T11:16:46.007 に答える