3

簡単にするために、ヘッダーMathFuncsDll.hを含むDLL_tokyo.dllの両方をルートフォルダーC:\に配置しました。

次に、空のプロジェクトを作成し、設定します

構成プロパティ->リンカー->入力->ロードされたDLLの遅延

C:\ DLL_tokyo.dll;%(DelayLoadDLLs)

構成プロパティ->VC++ディレクトリ->ディレクトリを含める

C:\; $(IncludePath)

コンパイラコマンド:

/ Zi / nologo / W3 / WX- / O2 / Oi / Oy- / GL / D "_MBCS" / Gm- / EHsc / MT / GS / Gy / fp:precise / Zc:wchar_t / Zc:forScope / Fp "Release \ clean_rough_draft.pch "/ Fa" Release \ "/ Fo" Release \ "/ Fd" Release \ vc100.pdb "/ Gd / analysis- / errorReport:queue

このプロジェクトには、mainを含むファイルのみが含まれています。

main.cpp

#include <Windows.h>
#include <iostream>
#include "MathFuncsDll.h"

using namespace MathFuncs;
using namespace std;

int main()
{
    std::cout<< MyMathFuncs<int>::Add(5,10)<<endl;

    system("Pause");
    return 0;
}

DLLは別のソリューションで正常にコンパイルされました。

MathFuncsDll.h

namespace MathFuncs
{
    template <typename Type>  
    class MyMathFuncs   
    {
    public:
        static __declspec(dllexport) Type Add(Type a, Type b);

        static __declspec(dllexport) Type Subtract(Type a, Type b);

        static __declspec(dllexport) Type Multiply(Type a, Type b);

        static __declspec(dllexport) Type Divide(Type a, Type b);

    };


}

これらの関数の定義:

#include "MathFuncsDll.h"

#include <stdexcept>

using namespace std;

namespace MathFuncs
{
    template <typename Type>
    Type MyMathFuncs<Type>::Add(Type a,Type b)
    { return a+b; }

    template <typename Type>
    Type MyMathFuncs<Type>::Subtract(Type a,Type b)
    { return a-b; }

    template <typename Type>
    Type MyMathFuncs<Type>::Multiply(Type a,Type b)
    { return a*b; }

    template <typename Type>
    Type MyMathFuncs<Type>::Divide(Type a,Type b)
    { 
        if(b == 0) throw new invalid_argument("Denominator cannot be zero!");
        return a/b; 
    }
}

このプログラムの実行は失敗します:

1> main.obj:エラーLNK2001:未解決の外部シンボル "public:static int __cdecl MathFuncs :: MyMathFuncs :: Add(int、int)"(?Add @?$ MyMathFuncs @ H @ MathFuncs @@ SAHHH @ Z)1> C:\ Users \ Tomek \ Documents \ Visual Studio 2010 \ Projects \ clean_rough_draft \ Release \ clean_rough_draft.exe:致命的なエラーLNK1120:1つの未解決の外部

私の間違いを指摘してもらえますか?

4

1 に答える 1

3

この問題は、DLLのロードの遅延とは関係ありません。ここで2つの問題が発生します。

  1. テンプレート化された関数をエクスポートしています。テンプレートのエクスポートはVisualC++コンパイラではサポートされていませんが、すでに標準から削除されているため、これはそのようには機能しません。これを機能させるには、2つの可能な解決策があります。

    • メソッドの実装を.hファイルに移動します。これにより、すべてのコードがヘッダーファイルに含まれるため、DLLはまったく必要なくなります。
    • クライアントアプリケーションで使用するタイプでテンプレートをインスタンス化します。これは、cppファイルに正確な型のインスタンス化コードを入れたりextern template、ヘッダーでいくつかの宣言を行ったりすることで行われます。詳細については、Googleで検索できます。「externtemplateDLL」などを検索してください。
  2. DLLを作成するときにメソッドをエクスポートするだけで、インポートすることはありません(または、少なくともコードからはそれがわかります)。各メソッドの前で使用__declspec(dllexport)します。これは、コンパイラにそのメソッドをDLLに入れるように指示します。クライアントアプリケーションからこれらのメソッドを使用する場合は、DLLからインポートする必要があります。これは__declspec(dllimport)、各メソッドの前に配置することによって行われます。メソッドに両方のプレフィックスを付けることはできないため、そのメソッドプレフィックスとは異なる2つのほぼ同じヘッダーファイルを作成するか、これがDLL構築コードであるかクライアントアプリケーションであるかに基づいてマクロ置換を使用する必要があります。もう一度、あなたはそれがどのように行われたかを見るためにグーグルでそれを調べることができます。

それがお役に立てば幸いです。

于 2012-08-22T05:54:43.553 に答える