8

ホストアプリケーションのSTLコンテナに保存されているデータにアクセスする必要があるDLLがあります。C ++には標準のABIがなく、さまざまなコンパイラをサポートしたいので、アプリケーションとDLLの間のインターフェイスは、基本的にプレーンな古いデータのままにする必要があります。

ベクトルの場合、これは比較的簡単です。ベクトルのメモリブロックは連続していることが保証されているため、単純に返すことができます。

// To return vector<int> data
virtual void GetVectorData(const int*& ptr, size_t& count) const
{
    if (!vec.empty())
        ptr = &(vec.front());

    count = vec.size();
}

これで、DLLは、そのインターフェイスを介してベクターのデータに安全に読み取り専用でアクセスできるようになります。DLLはこれをラップして、コンテンツをそれ自体のベクターにコピーすることもできます。

STLリスト(および両端キュー)はどうですか?DLL境界を介したアクセスを許可する別の簡単な方法はありますか?それとも、ある種のGetFirst()/ GetNext()インターフェイスに頼る必要がありますか?多くのリストに対してこれを行う必要があるかもしれないので、ベクトルのような単純なソリューションがあると便利です。

4

3 に答える 3

10

各stlタイプをインスタンス化する場所に注意すれば、DLL間でstlオブジェクトを渡し、さまざまなコンパイラをサポートできます。インテリジェントな「DLLEXPORT」マクロが必要です。VCとgccを正常にサポートするには、次のセットを使用します。

#ifdef WIN32
#ifdef MYDLLLIB_EXPORTS      // DLL export macros
#define MYDLLLIB_API __declspec(dllexport)
#define MYDLLLIB_TEMPLATE
#else
#define MYDLLLIB_API __declspec(dllimport)
#define MYDLLLIB_TEMPLATE extern
#endif
#else                       // Not windows --- probably *nix/bsd
#define MYDLLLIB_API
#ifdef MYDLLLIB_EXPORTS
#define MYDLLLIB_TEMPLATE
#else
#define MYDLLLIB_TEMPLATE extern
#endif
#endif // WIN32

DLLをコンパイルするときは、MYDLLLIB_EXPORTSを定義します。DLLで、使用する各stlタイプ(たとえば、文字列のリストやベクトルなど)をインスタンス化できます。

MYDLLLIB_TEMPLATE template class MYDLLLIB_API std::vector<std::string>;
MYDLLLIB_TEMPLATE template class MYDLLLIB_API std::list<std::string>;

DLLのコンシューマー(MYDLLLIB_EXPORTSが定義されていない)には、次のように表示されます。

extern template class __declspec(dllimport) std::vector<std::string>;

独自のインスタンス化する代わりに、DLLからエクスポートされたバイナリコードを使用します。

于 2009-12-11T09:49:47.683 に答える
7

おそらく、「ハンドル」のようなものをリスト/デキューイテレータに渡すことができますか?これらのハンドルタイプは不透明であり、ユーザーに出荷するヘッダーファイルで宣言されます。内部的には、ハンドル値をリスト/両端キュー反復子にマップする必要があります。基本的に、ユーザーは次のようなコードを記述します。

ListHandle lhi = GetListDataBegin();
const ListHandle lhe = GetListDataEnd();

while (lhi != lhe)
{
  int value = GetListItem(lhi);
  ...
  lhi = GetNextListItem(lhi);
}
于 2009-12-10T15:23:39.083 に答える
1

アプリケーションとDLLの間のインターフェースは、基本的にプレーンな古いデータのままである必要があります。

必ずしも。同じコンパイラバージョンが使用されていることを確認する必要があります。また、STLオブジェクトのレイアウトに影響を与えるビルド設定は、dllとアプリケーションの間でまったく同じです。

dllを公開する場合は、dllの境界を越えてSTLを公開することを心配する必要があります。ただし、すべてが管理下にあり、純粋に内部的なものである場合(または、サードパーティのビルド設定/コンパイラを厳密に適用できる場合)は、問題ないはずです。

于 2009-12-10T15:00:30.743 に答える