基於C#的Metro工程如何引用C++的動態庫——FIleNotFound解決辦法

    這是個折磨了我兩天的難題,每每在我感覺找到問題所在的時候,又總是差了那麼一點兒揭開謎底。

    過程是這樣的:我有個C#寫的metro風格的工程,其中引用了C++的dll,我們知道C#是不能直接調用C++的類庫,所以需要封裝一個wrapper層,也就是個運行時組件(WinRT Component)。詳見這裏:http://msdn.microsoft.com/en-us/library/windows/apps/hh441569(v=vs.110).aspx

    我在x86架構下編譯運行正常。隨後我希望能編譯個ARM版本,跑在Surface上面。並且,我需要將生成Component的工程從solution裏移除,這樣,就相當於我只爲別人提供一個wrapper層的dll和winmd文件,別人即可編寫自己的APP調用我的C++庫了。

    我把winRT Component工程移除,並且在configuration manager中將編譯target改爲arm,此時需要在Project菜單中將winRT Component工程生成的winmd文件加入到reference中。我通過點擊Browse的方式找到winmd位置並添加。此時,編譯正常。但是問題來了:當我remote debug到Surface上的時候,一旦調用到wrapper層的接口,就會報出“FileNotFound,找不到指定模塊”的異常。

    開始我懷疑dll沒有加載成功,可是查看了APPx文件夾,裏面是已經正確copy了dll的。並且如果再次向工程中添加一個dll時,會提示衝突,這說明dll已經加載進來了。

    經測試,如果再將winRT Component工程添加到solution,然後先移除原來已經添加的reference,再選擇“add reference —— 選擇solution--Projects”,然後勾選winRT Component工程,點擊OK。此時相當於從solution中添加了winRT Component工程的引用。這樣,遠程調試是沒有問題的。

    於是我對比了這兩次(一次成功,一次失敗)的manifest文件,發現成功的那次比失敗的多了這麼一句:

  <Dependencies>

    <PackageDependency Name="Microsoft.VCLibs.110.00.Debug" MinVersion="11.0.50727.1" />

  </Dependencies>

也就是說因爲沒有這個PackageDependency 才導致調試失敗,而缺少的是Microsoft.VCLibs.110.00.Debug,也就是說系統庫缺失!

隨後回到工程“add reference —— 選擇windows--Extensions——勾選Microsoft Visusl C++ Runtime Package”,確定,重新編譯。問題解決!

回頭分析了一下這個問題:問題雖小,一個勾選就能解決,但是查起來卻着實不易。主要是對C#比較陌生,而且Metro程序玩的太少。

http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/ed405c8c-c650-4c36-aaae-d81620de62c8/  這裏有篇文章給了很大啓示,其中Rob的回答中說Microsoft.VCLibs.110.00.Debug這個庫是C++和JS工程需要的。如果你的工程是C++或JS的,那麼VS會自動幫你加上這個庫,而C#的工程是不需要的,所以VS默認不會幫你加上(這也是我之前成功和失敗兩次manifest文件差別的原因)。由於我的APP是C#的,所以VS沒有幫我加這個庫,但是又由於我調用了C++的dll,所以必須要這個庫纔可以調試,因此導致了這一錯誤。望以後碰到類似問題的同學能注意到這點。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章