質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
DLL

DLL(Dynamic Link Library)とは、他のモジュールからも使用する事が出来る、関数とデータが格納されているモジュールのことです。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

Q&A

解決済

5回答

6627閲覧

1つのDLLファイルの参照先をプログラム内で変更する。

nmoki

総合スコア12

DLL

DLL(Dynamic Link Library)とは、他のモジュールからも使用する事が出来る、関数とデータが格納されているモジュールのことです。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

0グッド

0クリップ

投稿2017/07/12 01:32

編集2017/07/13 00:07

Oracle.Data.AccessやExcelCreatorを使用したアプリケーションの開発では、x64とx86のdllファイルが用意されています。
Oracle.Data.AccessやExcelCreatorはx64とx86でフォルダを分け、普段はx64のDll
を参照し、x86の実行環境の場合にx86のDLLを使用するように、参照先を変更することは可能でしょうか。
調べているうちにSetDllDirectoryが挙げられていたのですが、
SetDllDirectoryを使用すると、他のDLLファイルの参照先も変わってしまうのでしょうか。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答5

0

x86の実行環境ではx86フォルダのDLL、x64ならx64フォルダのDLLを参照先を変えて読み込むとなると、DLLを読み込むホストアプリも当然x86とx64の両方用意することになります。

WindowsのDLLの検索場所と優先度は以下のような感じになっていて、

  1. 実行したexeファイルと同じディレクトリ
  2. プロセスのカレントディレクトリ(ショートカット等で指定されている作業フォルダ)
  3. Systemディレクトリ
  4. windowsディレクトリ
  5. 環境変数PATHで指定されたディレクトリ

SetDllDirectoryはそのうち2番の参照先を変更するAPIになり、
1度変更すると再度設定しない限り、現在のプロセス内でのDLLの呼び出し全てに影響します。
libを使ったDLLの暗黙的リンクとLoadLibrary等の動的リンクでDLLの絶対パスを指定しなかった場合の両方に影響します。

単一のDLLの読み込み場所を指定するとなるとLoadLibraryでDLLの絶対パスを渡して動的リンクし、GetProcAddressで個別にDLL内の関数を呼び出して使う形になると思います。
しかし、LoadLibraryでパスを指定して呼び出したDLLが更に別のDLLに依存している場合も、DLLの検索PATHの影響を受けるのでややこしいことになります。

例えばx64フォルダにlibpng.dllzlib1.dllがあって、libpng.dllzlib1.dllに依存しています。

LoadLibraryでlibpng.dllを読み込もうとすると、libpng.dllが内部で依存しているzlib1.dllを呼び出そうとします。
しかし、DLLの検索PATHにはx64フォルダが含まれていないためlibpng.dllと同じフォルダに存在するにもかかわらず、zlib1.dllが見つからないとエラーが出るのです。

投稿2017/07/12 08:32

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/07/12 09:07

後から気が付いたのですが、AnyCPUが…って事はC#かVB.NETが対象でしょうか? C++等のネイティブなアプリケーションを想定していたので、.NETのアプリケーションだとこの回答は当てはまらないかもしれません。 タグにC# or VB.NET等の対象言語も追加したほうがより良い回答が得られるかもしれません。 ↓の連載記事が役に立つかも? http://www.atmarkit.co.jp/fdotnet/technology/idnfw11_02/idnfw11_02_04.html
nmoki

2017/07/13 00:09

回答、並びにアドバイスありがとうございます。 連載記事を参考にしてみます。
guest

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を動的に読み出すという方法があります。

ただし、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

skitoy4321

総合スコア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

hmmm

総合スコア818

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nmoki

2017/07/13 03:07

回答ありがとうございます。
guest

0

x86とx64のDLLを読み替えるということでしょうか。
たぶん無理だったと思います。x86、x64のどちらでビルドしたかで、読み込めるDLLは決まるはずです。
プラットフォームと違うDLLを読んだ時点で例外で落ちると思われます。

投稿2017/07/12 07:59

mugicya

総合スコア1046

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nmoki

2017/07/12 08:24

回答ありがとうございます。 AnyCPUでビルドを行い、クライントの環境によってDLLを読み替えることは同じく不可能でしょうか。
mugicya

2017/07/13 05:14

それぞれのクライアントを用意する必要がありますね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問