トップ回答者
外部DLLの参照ができない?

質問
-
VC++で既存のDLLをラップして拡張版DLLを作成しようとしているのですが、最初でつまづきました。
Visual Studio 2015 でプロジェクトの新規作成から、Win32コンソールアプリ > DLLと
選択してプロジェクトを作成し、いざオリジナルのDLLを取り込もうとして
ソリューションエクスプローラのReferencesを右クリック、「参照の追加」から参照追加の
ダイアログを開いたまではいいのですが、ダイアログ上のメッセージで
『項目が見つかりませんでした』
という表示だけが出て、ボタンはOKとキャンセルしかなく、参照の追加ができないため
全く先に進めなくなりました。内部でMFCを使う理由は特になく、配布時の簡易さやファイルサイズなどから、MFC DLLでなく
できればWin32 DLLの方が望ましいと考えているのですが、Win32コンソールアプリ の DLL
としてプロジェクトを作成する場合、外部DLLの参照はできないという制約などがあるのでしょうか。
回答
-
とりあえず前提として、.NETのライブラリがあり、それを活用したい、というケースを考えます。
まず、.NETをネイティブのC++から直接扱うのはきわめてハードルが高いので考慮外とします。
次善の策としてC++/CLIを使用するという選択肢があります。C++/CLIであればダイレクトに.NETオブジェクトを扱うことができます。が、C++/CLIも、十分にC++および.NETに習熟した方でないと色々難しい面があります。
そもそも、.NETの範囲に限定すれば、C++/CLIとC#で実現できることに差はなく、かつC#は最新の言語サポートによって様々な便利な機能が使用できます(例えばyieldであったり、async/awaitであったり、$""であったり)。
C++/CLIの利点としては、ネイティブのC/C++の既存ライブラリを使用するのに有利な面があるため(.hを直接includeできる)、あえて使うとすればできる限りネイティブの既存資産を活かしたいケースぐらいでしょうか。
新規開発でC++を使用するというのであればそれはそれで十分選択肢だと思いますが、.NETのライブラリがありそれを使用したい、というのであれば、C++/CLIを選択肢に入れる意味はないと思います。
- 回答の候補に設定 立花楓Microsoft employee, Moderator 2017年7月20日 2:18
- 回答としてマーク 立花楓Microsoft employee, Moderator 2017年7月20日 8:35
-
https://social.msdn.microsoft.com/Forums/ja-JP/88999bee-f3cc-4111-8862-325367e80236/vc?forum=vsgeneralja からの派生質問ですね。
最終的にはWindowsのフォームアプリケーションとしてDLLを利用したいのですが、C++/CLIの場合、VC++ 2010以降はWindowsのフォームアプリケーションとしては非推奨でしたので、UIとしてはC++のMFC(標準)を使うことになると考えていました。
(フォームアプリケーションのソースとしては、C++であることを要望されています)いわゆる「フォームアプリケーション」は「Windows フォームアプリケーション」というフレームワークを使ったアプリケーションを指すことが多いので、MFC の場合、「フォームアプリケーション」にはならないと思います。
また、MFC の場合、デザイナーはないと考えてください。
MFC のウィンドウクラスを元に、コードで画面を作り上げていくフレームワークなので、作り上げるまでにどのくらいの苦労をするのか、お試しでも良いので、早めに難易度把握をしておいた方が良いと思えます…。C++ MFC(ネイティブのC++?)から利用することはかなりハードルが上がってしまう、ということでしょうか。
基本的に、.NET の DLL はネイティブアプリケーションから利用することはできません。
C++/CLI で C や C++ の関数・クラスとしてうまくラップしてエクスポートするか、.NET の DLL を COM として公開するかが必要です。
どちらも、相応に手間がかかることを求められるので、C++ 経験が十分でない中、最終的なアプリケーション(GUI)を作る言語として C++ を選ぶことはまったくおすすめできません。
(.NET のオブジェクトの生存期間がどうなるか?といったあたりとか、HWND や HDC から Graphics に変換するとかは、最低限として必要となってきます)ステークホルダーが C++ を望む背景を確認することを早めにした方が良いです。
(経験談として、.NET しか経験がない人が、C/C++ を手につけ始めると、大抵メモリリークや Access Violation のオンパレードで、頭を抱えることになりやすいです…)
また、どうしても C++ で進めることが避けられないなら、C++ の経験者(熟練者)を早めにチームに組み入れた方が良いと思われます。
また、ステークホルダーが C++ をかたくなに希望し、C++/CLI & Windows Forms が非推奨でもそれを使って欲しいと望むなら、あえて MFC に逃げる必要もなくなりますね。
-----
あとは、拡張元の .NET DLL を使うことで、純粋なネイティブアプリケーションには仕上がりません。
ステークホルダーの要求が不明瞭ですが、最終的なアプリケーションが .NET Framework に依存することでもかまわないかどうかも気にはなります。
.NET Framework に依存しない、純粋な C++ アプリなら今の路線は間違っていることになりますので。- 編集済み AzuleanMVP, Moderator 2017年6月19日 13:03
- 回答の候補に設定 立花楓Microsoft employee, Moderator 2017年7月20日 2:18
- 回答としてマーク 立花楓Microsoft employee, Moderator 2017年7月20日 8:35
-
例えばyieldであったり、async/awaitであったり、$""であったり
脱線気味ですが、C++言語も進化していて今やco_yield、co_awaitなどをサポートしていますよ(Windows と C++ - Visual C++ 2015 におけるコルーチン)。もっとも.NETには依存していないためTaskクラスと連携するわけではありませんが。また$""はありませんね。- 回答の候補に設定 立花楓Microsoft employee, Moderator 2017年7月20日 2:18
- 回答としてマーク 立花楓Microsoft employee, Moderator 2017年7月20日 8:35
すべての返信
-
追記します。
環境はVisual Studio Community 2015 ; OSはWindows7 Professional です。
参照追加の ダイアログを表示させたとき、ペインには「プロジェクト」と「共有プロジェクト」
の2つが表示されるのですが、どちらを選択してもペイン中央に 『項目が見つかりませんでした』
というメッセージだけが出ます。
少し古い情報ですが、取り込みたいDLL(独自アセンブリ)を強制的に表示させる方法として、
以下のレジストリ配下に任意のキー(ここではMyAssemblyFolderとしました)を追加し、
DLLの格納先ディレクトリを指定するというやり方もあるようなので試してみましたが状況は変わらずでした。
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\AssemblyFolders\
-
その既存のDLLというのは、ネイティブのDLLでしょうか、それとも.NETのDLLでしょうか。
// あるいはActiveXのDLLとか。
分からないのであれば、とりあえず確認として新しくC#のプロジェクトを作成し、そのDLLを参照してみて下さい。C#からそのまま参照できるのであれば.NETの、そうでなければネイティブのDLLとみていいでしょう。
.NETのDLLなのであれば、ネイティブなC/C++ではなく、C#を使いましょう。C++/CLIという選択肢は恐らくハードルが高いです。
ネイティブのDLLなのであれば、.NETのアセンブリ参照的な使い方はできません。一般的なC/C++では、ヘッダファイル(.h)のインクルードと、ライブラリファイル(VC++では.lib)のリンクで対応します。
- 回答の候補に設定 立花楓Microsoft employee, Moderator 2017年6月20日 0:13
-
ありがとうございます!
試しにC#の「クラスライブラリ」としてプロジェクトを起こしてみたところ、参照でき、入力支援でメンバも表示されたので、
.NETのDLLということになるのだと思います。
どうやらC#での実装の方が自然なようなので、アドバイスいただいたようにひとまずはC#で進めることで問題がないか
関係者に確認してみたいと思います。(個人的にもC#でいきたいです)
なお不勉強で申し訳ないのですが、C++だとハードルが上がってしまうというのは、C++(またはCLI)自体の難易度としてでしょうか、
それとも、.NETのDLLを取り込む、あるいはDLLを作成する際に多くの注意が必要ということでしょうか。
もともと今回案件のベースがC++であり、一般的な情報としてC++でのDLL実装の例も多くあるようだったので、
そこにはあまり疑問を持っていなかったもので。。
-
とりあえず前提として、.NETのライブラリがあり、それを活用したい、というケースを考えます。
まず、.NETをネイティブのC++から直接扱うのはきわめてハードルが高いので考慮外とします。
次善の策としてC++/CLIを使用するという選択肢があります。C++/CLIであればダイレクトに.NETオブジェクトを扱うことができます。が、C++/CLIも、十分にC++および.NETに習熟した方でないと色々難しい面があります。
そもそも、.NETの範囲に限定すれば、C++/CLIとC#で実現できることに差はなく、かつC#は最新の言語サポートによって様々な便利な機能が使用できます(例えばyieldであったり、async/awaitであったり、$""であったり)。
C++/CLIの利点としては、ネイティブのC/C++の既存ライブラリを使用するのに有利な面があるため(.hを直接includeできる)、あえて使うとすればできる限りネイティブの既存資産を活かしたいケースぐらいでしょうか。
新規開発でC++を使用するというのであればそれはそれで十分選択肢だと思いますが、.NETのライブラリがありそれを使用したい、というのであれば、C++/CLIを選択肢に入れる意味はないと思います。
- 回答の候補に設定 立花楓Microsoft employee, Moderator 2017年7月20日 2:18
- 回答としてマーク 立花楓Microsoft employee, Moderator 2017年7月20日 8:35
-
最終的にはWindowsのフォームアプリケーションとしてDLLを利用したいのですが、
C++/CLIの場合、VC++ 2010以降はWindowsのフォームアプリケーションとしては非推奨
でしたので、UIとしてはC++のMFC(標準)を使うことになると考えていました。
(フォームアプリケーションのソースとしては、C++であることを要望されています)
拡張版のDLL自体をC#で作ったとしても、拡張元のオリジナルDLLが.NETのDLLである場合、
C++ MFC(ネイティブのC++?)から利用することはかなりハードルが上がってしまう、ということでしょうか。
-
https://social.msdn.microsoft.com/Forums/ja-JP/88999bee-f3cc-4111-8862-325367e80236/vc?forum=vsgeneralja からの派生質問ですね。
最終的にはWindowsのフォームアプリケーションとしてDLLを利用したいのですが、C++/CLIの場合、VC++ 2010以降はWindowsのフォームアプリケーションとしては非推奨でしたので、UIとしてはC++のMFC(標準)を使うことになると考えていました。
(フォームアプリケーションのソースとしては、C++であることを要望されています)いわゆる「フォームアプリケーション」は「Windows フォームアプリケーション」というフレームワークを使ったアプリケーションを指すことが多いので、MFC の場合、「フォームアプリケーション」にはならないと思います。
また、MFC の場合、デザイナーはないと考えてください。
MFC のウィンドウクラスを元に、コードで画面を作り上げていくフレームワークなので、作り上げるまでにどのくらいの苦労をするのか、お試しでも良いので、早めに難易度把握をしておいた方が良いと思えます…。C++ MFC(ネイティブのC++?)から利用することはかなりハードルが上がってしまう、ということでしょうか。
基本的に、.NET の DLL はネイティブアプリケーションから利用することはできません。
C++/CLI で C や C++ の関数・クラスとしてうまくラップしてエクスポートするか、.NET の DLL を COM として公開するかが必要です。
どちらも、相応に手間がかかることを求められるので、C++ 経験が十分でない中、最終的なアプリケーション(GUI)を作る言語として C++ を選ぶことはまったくおすすめできません。
(.NET のオブジェクトの生存期間がどうなるか?といったあたりとか、HWND や HDC から Graphics に変換するとかは、最低限として必要となってきます)ステークホルダーが C++ を望む背景を確認することを早めにした方が良いです。
(経験談として、.NET しか経験がない人が、C/C++ を手につけ始めると、大抵メモリリークや Access Violation のオンパレードで、頭を抱えることになりやすいです…)
また、どうしても C++ で進めることが避けられないなら、C++ の経験者(熟練者)を早めにチームに組み入れた方が良いと思われます。
また、ステークホルダーが C++ をかたくなに希望し、C++/CLI & Windows Forms が非推奨でもそれを使って欲しいと望むなら、あえて MFC に逃げる必要もなくなりますね。
-----
あとは、拡張元の .NET DLL を使うことで、純粋なネイティブアプリケーションには仕上がりません。
ステークホルダーの要求が不明瞭ですが、最終的なアプリケーションが .NET Framework に依存することでもかまわないかどうかも気にはなります。
.NET Framework に依存しない、純粋な C++ アプリなら今の路線は間違っていることになりますので。- 編集済み AzuleanMVP, Moderator 2017年6月19日 13:03
- 回答の候補に設定 立花楓Microsoft employee, Moderator 2017年7月20日 2:18
- 回答としてマーク 立花楓Microsoft employee, Moderator 2017年7月20日 8:35
-
例えばyieldであったり、async/awaitであったり、$""であったり
脱線気味ですが、C++言語も進化していて今やco_yield、co_awaitなどをサポートしていますよ(Windows と C++ - Visual C++ 2015 におけるコルーチン)。もっとも.NETには依存していないためTaskクラスと連携するわけではありませんが。また$""はありませんね。- 回答の候補に設定 立花楓Microsoft employee, Moderator 2017年7月20日 2:18
- 回答としてマーク 立花楓Microsoft employee, Moderator 2017年7月20日 8:35
-
Hongliangさん、Azuleanさん、佐祐理さん
いくつもの有用なアドバイスを頂き、ありがとうございます。
技術上のピンポイントの問題点もありますが、それよりもまずは2つのスレッドを通じて、構成の再検討を含めて情報ときっかけを頂いた事は大変重要なアドバイスを頂戴したと思っています。頂いたコメントを踏まえて、顧客要求の再確認と、技術上の調査、検証などの検討を少し進めてみたいと思います。
内容的に、方針が決まるまで少し時間がかかることが予想されますので、この質問としてはここまでとさせて頂こうと思います。
方針がある程度決まったうえで、また具体的な課題などが出てきた際には、別途ご相談させていただくかもしれませんので、その際は是非また、どうぞよろしくお願いいたします。コメント頂いた皆さま、本当にどうもありがとうございました。 m(_ _)m