私は、ABI 互換性のために互換性のある仮想テーブルの実装に依存する、COM スタイルのコンパイラ相互互換性プラグイン フレームワークに取り組んでいます。純粋な仮想メンバー関数とオーバーライドされた削除演算子のみを含むインターフェイスを定義して、破棄を実装の場所に送ります。これは、インターフェイスのプラグイン実装をインスタンス化し、インターフェイス型ポインターを返す extern "C" ファクトリ関数でうまく機能します。
しかし、スマート ポインターは、プラグイン オブジェクトの有効期間を管理するための最新の方法ではないのではないかと考えていました。プラグイン インターフェイスと同じ方法で定義および実装された参照カウント オブジェクトを使用する、標準レイアウトの shared_ptr/weak_ptr を実際に作成できたと思います。次のようになります。
class IRefCount
{
public:
virtual void incRef() = 0;
virtual void decRef() = 0;
virtual bool incRefIfNZ() = 0;
virtual void incWRef() = 0;
virtual void decWRef() = 0;
virtual long uses() const = 0;
protected:
~ref_count_base() = default; //prohibit automatic storage
}
template <typename Ty>
class shared_ptr
{
private:
Ty* ptr_;
IRefCount* ref_count_;
public:
//member functions as defined by C++11 spec
}
3 つの質問:
スマート ポインターの前は、ファクトリ関数は次のようになっていました。
extern "C" IPlugin* factory() { try { return new Plugin(); } catch (...) { return nullptr; } }
これで、次のようになります。
extern "C" shared_ptr<IPlugin> factory() { try { return shared_ptr<IPlugin>(new Plugin()); } catch (...) { return nullptr; } }
VS2013 で警告 C4190 が表示されます: 'factory' には C リンケージが指定されていますが、C と互換性のない UDT 'shared_ptr' が返されます。MSDN によると、呼び出し元と呼び出し先の両方が C++ であれば問題ありません。
「C」リンケージ関数から標準レイアウト オブジェクトを返すことに関して、他に潜在的な問題はありますか?
呼び出し規約。すべての純粋仮想インターフェイス関数とファクトリ関数に対して __stdcall を指定する必要がありますか?
<atomic>
参照カウントに使用しています。プラットフォームに依存しないコードを書いていますが、ARM 用のコンパイルはまだ試していません。http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dht0008a/ch01s02s01.htmlによると、armccはstd::atomicを実装していません。より良いコンパイラ/ stl はありますか?