2

私は現在、C++ (MSVS 2008) で独自のフレームワークを作成しています。これは、フレームワークのユーザーが使用/呼び出しするための一連の関数を含む dll をエクスポートします。私のプロジェクトがまだ小さかった当初、すべてがうまくいきました。プロジェクトをコンパイルしました。MyFramework.dll と MyFramework.lib が吐き出されました。私はユーザーのふりをしました。MyFramework.dll ファイルを新しい VS プロジェクトの Debug フォルダーに配置し、MyFramework.lib と MyFramework.h ファイルをプロジェクト フォルダーに配置し、#include-d MyFramework.h をコードに追加すると、(まだ単純な) を呼び出すことができます。私の新しいプロジェクト内からのフレームワーク関数。

しかし今、私はフレームワークを拡張しました。独自の外部 dll (Graphics.dll と呼びましょう) を使用し、同じ方法でインクルードしました (Debug フォルダーの .dll、プロジェクト フォルダーの .lib/.h、コードの #include Graphics.h)。

問題は、MyFramework.dll/MyFramework.lib を作成し、それを新しいプロジェクトに含めてビルドすると、リンカが、明らかに MyFramework.dll のどこかに含まれていた Graphics.h を含めることができないと文句を言うことです。

だから私の質問。MyFramework.dll のユーザーは、プロジェクトに MyFramework.* ファイルを含めるだけで済み、MyFramework で使用することにしたすべての外部ライブラリをコピーして貼り付ける必要はありません。どうすればこれを達成できますか? このスレッドを見てみました。既存のアイテムを追加し、「追加」ボタンの横にある小さな矢印を押すことについて何か言っていますが、... 私のバージョンの MSVS には矢印が存在しません...

助けていただければ幸いです。

敬具 W.スペック

4

3 に答える 3

2

何が起こっているのかというと、ユーザーはライブラリのヘッダーファイルの1つをインクルードしています。このファイルには「graphics.h」が含まれています。ユーザーにこのファイルへのアクセスを要求したくない場合は、ライブラリインターフェイスからファイルを非表示にする必要があります。

つまり、ライブラリにはパブリックapiヘッダーファイルとプライベート実装ヘッダーファイルが必要です。ユーザーにはパブリックAPIヘッダーファイルのみが含まれ、サードパーティまたはプライベートインクルードファイルは含まれません。これらのファイルがプライベートタイプまたはサードパーティタイプを参照する場合、それらはポインターまたは参照のみを使用でき、これらは前方宣言されます。これにより、クラスのプライベート部分でプライベートライブラリコードとサードパーティタイプを使用できるようになります。

Pimpl Idiomを使用している可能性がありますが、これは修正されます。

于 2009-10-15T13:14:00.263 に答える
1

「問題は、MyFramework.dll/MyFramework.lib を作成し、それを新しいプロジェクトとビルドに含めると、明らかに MyFramework.dll のどこかに含まれていた Graphics.h を含めることができないとリンカが文句を言うことです。」

ヘッダーファイルへのパスを入力しましたか? コンパイラは、ヘッダー ファイルが変換中の cpp ファイルと同じディレクトリになく、追加のインクルード ディレクトリにもリストされていないことを報告しています。

[プロジェクト] -> [プロパティ] に移動し、[C/C++] を選択します

最初に表示されるオプションは、「追加のインクルード ディレクトリ」です。そこにヘッダーGraphics.hへのパスを、すべてセミコロンで区切られた必要な他のパスとともに配置する必要があります。mo で開いているプロジェクトには、たとえば、「../AudioLibrary;../CoreLibrary;」があります。

編集: コメントからマークの投稿まで、Graphics.DLL を DLL に埋め込みたいと言っています。私の答えは次のとおりです。

Graphics.dll のソース コードがない場合は、問題があります。あなたが求めていることは可能ですが、行うのは非常に複雑です。基本的に LoadLibrary は使用できません。LoadLibaray と GetProcAddress の独自の for を作成する必要があります。これは、埋め込まれた DLL を調べて、ディスク上で見つけようとはしません...実行可能ですが、Portable Executable で多くの読み取りを行う必要があります ( PE) ファイル構造.

于 2009-10-15T10:22:12.000 に答える
0

ユーザーが Graphics.h を持ったり含めたりする必要がないようにする場合は、LoadLibrary実行時に Graphics.dll を動的にロードする方法があります。

これは、Graphics.dll が利用可能でなくてもユーザーが MyFramework に対してコンパイルできることを意味するため、LoadLibrary が失敗した場合は何らかのエラー報告を行うのが賢明かもしれません。

Graphics.dll の呼び出しに成功したらLoadLibrary、次を使用して各関数 (およびその署名) を手動でインポートする必要がありますGetProcAddress。これにより、実際に関数ポインターが得られます。関数ポインタをどのように格納するかはあなた次第です。私は通常、インポートされた関数をクラスでラップすることを好みますが、関数ポインタをグローバル スコープに保持することを妨げるものは何もありません。


コメントで述べたように、Graphics.dll をまったく配布 したくない場合は、静的ライブラリ (つまり、MyFramework.dll に「組み込まれている」) である必要があります。Graphics.dll を配布したい場合(ユーザーが MyFramework.dll なしで Graphics.dll を使用できるようにするため) は、上記のアプローチがより適切なオプションです。実際、上記のアプローチは、Graphics.dll を MyFramework.dll と共に配布していることを前提としていますが、ユーザーが Graphics.h を利用できるとは限りません。

于 2009-10-15T10:57:18.857 に答える