Oracle.Data.AccessやExcelCreatorを使用したアプリケーションの開発では、x64とx86のdllファイルが用意されています。
Oracle.Data.AccessやExcelCreatorはx64とx86でフォルダを分け、普段はx64のDll
を参照し、x86の実行環境の場合にx86のDLLを使用するように、参照先を変更することは可能でしょうか。
調べているうちにSetDllDirectoryが挙げられていたのですが、
SetDllDirectoryを使用すると、他のDLLファイルの参照先も変わってしまうのでしょうか。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答5件
0
x86の実行環境ではx86フォルダのDLL、x64ならx64フォルダのDLLを参照先を変えて読み込むとなると、DLLを読み込むホストアプリも当然x86とx64の両方用意することになります。
WindowsのDLLの検索場所と優先度は以下のような感じになっていて、
- 実行したexeファイルと同じディレクトリ
- プロセスのカレントディレクトリ(ショートカット等で指定されている作業フォルダ)
- Systemディレクトリ
- windowsディレクトリ
- 環境変数PATHで指定されたディレクトリ
SetDllDirectory
はそのうち2番の参照先を変更するAPIになり、
1度変更すると再度設定しない限り、現在のプロセス内でのDLLの呼び出し全てに影響します。
libを使ったDLLの暗黙的リンクとLoadLibrary等の動的リンクでDLLの絶対パスを指定しなかった場合の両方に影響します。
単一のDLLの読み込み場所を指定するとなるとLoadLibraryでDLLの絶対パスを渡して動的リンクし、GetProcAddressで個別にDLL内の関数を呼び出して使う形になると思います。
しかし、LoadLibraryでパスを指定して呼び出したDLLが更に別のDLLに依存している場合も、DLLの検索PATHの影響を受けるのでややこしいことになります。
例えばx64
フォルダにlibpng.dll
とzlib1.dll
があって、libpng.dll
はzlib1.dll
に依存しています。
LoadLibraryでlibpng.dll
を読み込もうとすると、libpng.dllが内部で依存しているzlib1.dll
を呼び出そうとします。
しかし、DLLの検索PATHにはx64
フォルダが含まれていないためlibpng.dll
と同じフォルダに存在するにもかかわらず、zlib1.dll
が見つからないとエラーが出るのです。
投稿2017/07/12 08:32
退会済みユーザー
総合スコア0
0
確か Assembly.LoadFrom で動的ロードができたと思います。私が少し前に作ったアプリは、その方法で Temp ディレクトリに任意の dll を保存してロードして使えてました。
VB.NET
1Reflection.Assembly.LoadFrom("C:\Program Files (x86)\Oracle Developer Tools for VS2013\odp.net\managed\" & If(Environment.Is64BitProcess, "x64", "x86") & "\Oracle.ManagedDataAccessDTC.dll") 2
Oracleは詳しくないので良く分かりませんが、上記コードで適切なアセンブリをロードできているようです。ロードした後、DLLの呼び出し方法は試していませんが、以下のいずれかの方法でできると思います。
<32bitと64bitのアセンブリが同一と認識される場合>
1.読み込める方のDLLを参照設定して New でオブジェクトを作って呼び出す。(普通に使う)
<32bitと64bitのアセンブリが同一と認識されない場合>
1.Object型で遅延バインディングを使う。
2.Reflectionの機能を使って呼び出す。
投稿2017/07/13 14:24
退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
ベストアンサー
マネージドアセンブリ自体がx86/x64で分かれていた場合は、Windowsの.NET Framework限定ですが、
AppDomain.AssemblyResolveイベントを使って、DLLを動的に読み出すという方法があります。
- https://msdn.microsoft.com/en-us/library/system.appdomain.assemblyresolve(v=vs.110).aspx
- http://d.hatena.ne.jp/masa_m/20130108/1357644226
ただし、PCLモジュールが混ざっている場合は、以下のURLのように一工夫必要です。
https://stackoverflow.com/questions/18793959/filenotfoundexception-when-trying-to-load-autofac-as-an-embedded-assembly
対象がネイティブDLLの場合、DllImportのパラメーターにx64用とx86用のものを指定したクラスをそれぞれ作っておいて、Environment.Is64BitProcessで呼ぶクラスを分けるという手段があります。
投稿2017/07/13 02:20
総合スコア229
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
こういうのはどうでしょうか?
Kicker.exe
Main_x86.exe
Main_x86.exe.config
Main_x64.exe
Main_x64.exe.config
その他のdll(Any CPU)
lib_x86/x86ライブラリのdll
lib_x64/x64ライブラリのdll
というようにしてKicker.exeでx86/x64かを判定して対応するEXEを起動する。
Main_x86.exe.configには
<probing privatePath="lib_x86"/>
Main_x64.exe.configには
<probing privatePath="lib_x64"/>
と記載して追加でロードする場所を切り替える。
投稿2017/07/12 11:11
総合スコア818
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
x86とx64のDLLを読み替えるということでしょうか。
たぶん無理だったと思います。x86、x64のどちらでビルドしたかで、読み込めるDLLは決まるはずです。
プラットフォームと違うDLLを読んだ時点で例外で落ちると思われます。
投稿2017/07/12 07:59
総合スコア1046
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2017/07/12 09:07
2017/07/13 00:09