C#からネイティブDLLを呼び出す場合のVSからのデバッグのジレンマを解決する...

 

C#を使う最大のメリットって、やっぱり、Visual Studioですよね!」って自信を持って言いたいですね。

という心境ではあるんですが、私の仕事はどっちかというとC++よりなので、どうしても、DllImportはお友達という側面があります。そうすると、プログラム実行時に、

AnyCPUなアセンブリ.exe
ネイティブC++.dll

みたいな感じになって、要は、AnyCPUなアセンブリがネイティブC++ちゃんを呼び出す構図になるんですが、この構成、64-bitの環境で開発をしていたりすると相当なジレンマを抱えることになります。

普通に実行する場合には、x64環境なので、「ネイティブC++.dll」さんは、64-bit版を配置しておくべきなんですが、VS上からデバッグしようとすると、win32(32-bit版)を置いておかないと行けなかったり、あるいは、「ネイティブC++.dll」さんのデバッグ版は激遅なので、デバッグ中でも普通はリリース版を置いておきたかったりと、様々な面倒なシチュエーションに出くわすことになります。

で、これを解決する方法を考えたよという話です。
簡単に言うと、

AnyCPUなアセンブリ.exe
win32/
  ネイティブC++.dll
x64/
  ネイティブC++.dll

というディレクトリ構成にしてしまえという。「AnyCPUなアセンブリ.exe」は、賢いので、自分が実行されている環境に応じて、どっちをロードするか見てくれるという。

で、どうするかというと、次みたいなコードをアプリに取り込んでしまえという。
これは、MainWindow.xaml.csとかの例ですが、もっと早い段階がよければ、そこでやっても良いですね:

static MainWindow()
{
  SetDllDirectory("");
#if DEBUG
  if (setDllLocation(true))
    return; #endif setDllLocation(false); } /// <summary> /// Controlling DLL directory which native DLLs are loaded from. /// </summary> /// <param name="debug">Whether this is debug mode or not.</param> /// <returns><c>true</c> if DLL directory is correctly set; otherwise <c>false</c>.</returns> static bool setDllLocation(bool debug) { var appDir = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); if (debug) appDir = Path.Combine(appDir, "debug"); var dllDir = Path.Combine(appDir, IntPtr.Size == 8 ? "x64" : "win32"); if (Directory.Exists(dllDir)) { Debug.WriteLine(string.Format("Set DLL Location ({0}): {1}", debug ? "Debug" : "Release", dllDir)); SetDllDirectory(dllDir); return true; } return false; } [DllImport("Kernel32.dll")] static extern bool SetDllDirectory(string lpPathName); 

やってることの内容としては、 SetDllDirectory APIを呼び出して、DLLをロードするディレクトリを事前に変更しておこうと。
C++だと、delayloadがらみを調整して同じような事が出来ますが、C#でのDllImportは完全に実行時にバインディングを解決することになるので、かなりこういう芸当がやりやすいです。

で、上のコードにはオマケがあって、デバッグ版では、さらに、

AnyCPUなアセンブリ.exe
debug/
  win32/
    ネイティブC++.dll
  x64/
    ネイティブC++.dll

みたいなレイアウトにしておけば、デバッグ版のDLLを見つけてロードしてくれると。
いずれにしても、デバッグ時にDLLをコピーしたり移動したりの右往左往がかなり軽減されるという意味では開発が楽になると思います。

转载于:https://www.cnblogs.com/xpvincent/p/9903416.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值