基于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,所以必须要这个库才可以调试,因此导致了这一错误。望以后碰到类似问题的同学能注意到这点。

你可能感兴趣的:(C#,Metro工程,C++动态库,FIleNotFound)