1

現在、Visual Studio を使用しています。dll api 関数とクラスをマークする古典的なマクロがあります。私の理解では、クラス dllexport をマークすると、その関数が他のバイナリから見えるようになり、dll によって提供される型を使用できるようになります。

クラスにテンプレート メンバー関数が含まれている場合の dllexport と dllimport の動作について教えてください。私の最初の疑いは、それらを無視するだけであり、それがまさに私が望んでいることです。

しかし、MSDN でこの特定のケースを説明している場所を見つけることができません (ただし、他のケースについて説明しています)。

例:

    class MY_API Log // MY_API is either __declspec( dllexport ) or __declspec( dllimport ) depending on if we are compiling the library or using it's header
    {
    public:

            // is this ignored?
        template< typename TypeOfSomething >
        Log& write( const TypeOfSomething& something ) 
        {
            test_stream << something;
        }

        ~Log(); // ok this is exported/imported

    private:
          std::stringstream text_stream;
    };

この例を示すためにコードを単純化しました。

私が疑っているのは、クライアント コードが write() 関数を使用すると、テンプレートがインスタンス化され、実際の関数コードが生成され、インライン化される可能性があるということです。この場合、コンパイラは、すべてのメンバー関数と同じように "dllimport" とマークしますか? それとも、何もせずにクライアント コードでそのバージョンを使用するだけですか?

4

1 に答える 1

1

「テンプレート関数」のようなものはありません。C++には関数テンプレートがあります。

関数テンプレートは関数ではありません。関数を生成するためのレシピです。コンパイルされたプログラムやDLLには存在しません。タイプもアドレスもありません。それらをインポートまたはエクスポートすることはできません。

テンプレートから生成された関数(別名関数テンプレートのインスタンス化)は通常の関数です。それらはDLLに入れられ、インポートおよびエクスポートされます。しかし、通常、そうすることはほとんど意味がありません。関数テンプレートは通常、ヘッダーファイルのソースフォームに存在するため、DLLからインスタンス化をインポートする必要はありません。特に、DLLには固定された有限のインスタンス化のセットしか含めることができず、ライブラリのユーザーは、そこにないインスタンス化を常に要求できます。

特定の固定されたインスタンス化のセットをDLLに配置することが正当化される場合もありますが、そのような場合はまれです。

于 2012-07-19T14:43:22.500 に答える