1

私の現在のプロジェクトは、CとC++のインターフェイスを同時に持つことを目的とした中規模のライブラリです。これは、CおよびC ++関数からアクセスできるようにしたい単一のデータ型を中心にしています。これは、いずれかの言語で関数を記述してライブラリを拡張するようにサードパーティに推奨したいためです。

私はC/C ++ミキシングの基本について知っており(たとえばhttp://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.htmlと比較してください)、次の解決策を考え出しました。

私の基本的な設計は、すべてのデータを公開したCで構造体を作成し(これは私のCプログラマーが期待するものです)、メンバーアクセスを隠すクラスを派生させ、C++プログラマーが構造体に安全にアクセスできるようにすることを中心としています。問題は派生にあります。C++で名前空間を使用し、Cインターフェイスを非表示にしたいのです。もちろん、C構造体自体を非表示にすることはできません(PIMPLイディオムに頼らなければ)が、それは私にとっては問題ありません。

次のサンプルコードは、CおよびC++の「クライアント」プログラムで明らかなエラーなしにコンパイルおよび実行されます。しかし、私はこの解決策が有効であるかどうか、またはより良い解決策があるかどうか疑問に思っています。

コード例:

#ifdef __cplusplus__
extern "C" {
#endif

struct base
{
    char * data;
}

#ifdef __cplusplus__
} // extern "C"
namespace {
extern "C" {
#endif

/* cleanly initialize struct */
struct base * new_base (struct base *);

/* cleanly destroy struct */
void del_base (struct base *);

#ifdef __cplusplus__
} } // namespace, extern "C"

#include<new>

namespace safe {

class base_plus : private base
{
public:
    base_plus () 
    { 
        if (! new_base(this)) 
            throw std::bad_alloc ();
    }

    ~base_plus ()
    {
        del_base (this);
    }
};

} // namespace safe

#endif
4

1 に答える 1

3

実際には、別の方法は、C ++で完全なコードを記述し、データ隠蔽技術を使用して、これに対してCスリムインターフェイスのみを記述することです。

namespace Foo {
    class Bar {
    public:
        int property1() const;
        std::string const& property2() const;
    };
}

そして、C互換のヘッダーで:

#ifdef __cplusplus__
extern "C" {
#endif

typedef void* Bar;

Bar foo_bar_new(int i, char const* s);

void foo_bar_delete(Bar b);

int foo_bar_property1(Bar b);

char const& foo_bar_property2(Bar b);

#ifdef __cplusplus__
}
#endif

付随する実装で:

Bar foo_bar_new(int i, char const* s) {
    return new Foo::Bar(i, s);
}

void foo_bar_delete(Bar b) {
    delete static_cast<Foo::Bar*>(b);
}

int foo_bar_property1(Bar b) {
    return static_cast<Foo::Bar*>(b)->property1();
}

char const* foo_bar_property2(Bar b) {
    return static_cast<Foo::Bar*>(b)->property2().c_str();
}

2つの主な利点は次のとおりです。

  • 完全にカプセル化されたデータとより強力な型システムのすべての長所を備えた本格的なC++コード
  • リリース間のバイナリの安定性がCインターフェイスで容易になりました

注:これは、たとえば、ClangとLLVMがCの互換性を処理する方法です。

于 2012-11-04T14:15:26.387 に答える