1

プロジェクト外のいくつかのクラスにアクセスするdllがあります(Visual Studioを使用しているため、2つのプロジェクトがあります)。問題は、dllのプロジェクトの外部にある、dllに含まれるヘッダーには、次のような関数の本体しかないということです。

xh

class x
{
    void myFunc();
}

そして、dllファイルの外にある別のcppファイル:

#include "x.h"

x::myFunc()
{
    //.....
}

dllは関数の本体のみを取得しているため、コンパイルすると、未解決の外部シンボルが多数取得されます(.hファイルに完全に組み込まれた別のクラスでテストしたため、これが問題であると確信しています。別のプロジェクト、およびエラーなし)。では、どうすればこの謎を解くことができますか?

4

2 に答える 2

1

インポートヘッダーには関数シグネチャのみが含まれるのが普通です。実際の関数本体はすでにDLLバイナリにコンパイルされており、実際のDLLにリンクすることでリンク時に解決されます。

最初に試すことは、実際に上記のDLLにリンクしていることを確認することです。ヘッダーを含めるだけでは不十分です。バイナリにリンクする必要もあります。したがって、プロジェクト構成では、(たとえば)DLLがコンパイルされるときにDLLと一緒に作成される.libファイルへのリンクを追加する必要があります(MSVCの場合)。このlibファイルにより、リンカーは、インポートヘッダーを介してインクルードした関数シグニチャーをDLLに含まれる実際の実装に接続する方法を知ることができます。別のプラットフォームを使用している場合、メカニズムは少し異なる可能性がありますが、概念は似ています。

編集:次のステップは、バイナリがリンクしようとしているシンボルを実際にエクスポートしていることを確認することです。すべてのインターフェイス署名が__declspec(dll_export)プレフィックスを介してエクスポートされていることを確認してください。通常、これはIFDEFにラップされているため、DLLのコンパイル中にヘッダーがエクスポートとして宣言されますが、そのヘッダーがクライアントプロジェクトに含まれている場合は宣言されません。次に、dumpbinを使用して、マングルされたエクスポート名をチェックし、予期しないものがないかどうかを確認できます。

これは、このスタイルのエクスポートを示す例の修正バージョンです(注:これがコンパイルされるかどうかはテストしていません。タイプミスについてお詫びします)。

#ifdef BUILDING_MYDLL
#define MYDLL_API __declspec(dllexport)
#else
#define MYDLL_API __declspec(dllimport)
#endif

class MYDLL_API x
{
    void myFunc();
}

次に、dllのコンパイル時にBUILDING_MYDLLを定義するように構成を設定しますが、実行可能ファイルのコンパイル時には設定しません。このように、関数はライブラリdllをコンパイルするときにのみエクスポートとしてマークされます。これで、パブリックAPI関数をMYDLL_APIでマークでき、ビルド中にエクスポートされるはずです。

dll_export、dll_import、およびdeclspecは、すべて非常にMSVC固有の構造であることに注意してください。他のコンパイラ/ランタイムは、さまざまな方法でシンボルのエクスポートを処理します。

于 2012-11-01T23:01:17.767 に答える
1

DLLをWindowsのアプリにリンクする方法は複数あります。この既存の質問/回答を確認してください: https ://stackoverflow.com/a/2060508/1701823

于 2012-11-01T23:08:57.897 に答える