Windows 8 / WinRT中的Metro应用程序中的PInvoke

8
我有一个使用 Silverlight 5 Out-of-browser 制作的简单 FM 收音机调谐器应用程序,通过 PInvoke 调用我的 USB FM 接收器的 Native C++ DLL 中的代码。这个应用在 Windows 8 上与 Silverlight5 上运行得非常好。
现在我正在尝试将其移植到使用 WinRT 的 Metro 应用中。
从 Silverlight 到 XAML UI 的迁移相当容易且顺利。PInvoke 签名和属性可以使用 System.Runtime.InteropServices 命名空间和 DLLImport 属性进行正确检测。
问题是,在我运行应用并调用任何在我的 SL5 应用程序中正常工作(即使在 Windows8 上也能正常工作)的 PInvoked native DLL 方法时,我会遇到异常:
System.DllNotFoundException was unhandled by user code
  Message=Unable to load DLL 'CarTFTFM.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
  Source=metroradio
  TypeName=""
  StackTrace:
       at MetroRadio.FMRadio.HWInit2(Int32 port, Int32 initVolume)
       at MetroRadio.MediaService.InitializeRadio() in c:\Users\Gutemberg\Documents\Visual Studio 11\Projects\MetroRadio\MetroRadio\MediaService.cs:line 160
       at MetroRadio.MainPage.radio_Click(Object sender, RoutedEventArgs e) in c:\Users\Gutemberg\Documents\Visual Studio 11\Projects\MetroRadio\MetroRadio\MainPage.xaml.cs:line 43
  InnerException: 

所以,我的问题是,这个PInvoke有什么问题?因为它在Windows 8上与SL5应用程序一起运行良好,我看不出在WinRT / Metro应用程序中有任何问题的理由。


1
似乎包清单中缺少 DLL。当前文档过于晦涩,无法提供良好的链接。 - Hans Passant
看一下这个问题:https://dev59.com/3lzUa4cB1Zd3GeqP2FXh - Aleksandr Dubinsky
听起来很相似,但仍然没有成功... - Gutemberg Ribeiro
2
Metro应用程序不允许调用任何Win32函数。也许DLL在加载(DllMain)时使用了无效的调用,导致加载失败。请记住,它甚至还没有进入Beta测试阶段... - Emond
@GutembergRibeiro 我假设你现在已经解决了这个问题,但如果没有,请看一下我下面的答案。 - Anders Gustafsson
2个回答

5
根据Pavel Minaev回答Chris Pietschmann的答案:
P/Invoke和COM互操作在.NET Metro应用程序中肯定受支持。Win32 API也被支持,并且可以通过上述技术调用,尽管它仅限于Metro应用程序可用的那些函数(即如果C++ Metro应用程序不能调用它,则.NET应用程序也不能)。
正如Morten Frederiksen所指出的,CarTFTFM.dll很可能包含WinRT的未受支持部分的Win32 API表面:
只有Win32和COM API的子集得到支持:msdn.microsoft.com/en-us/library/windows/apps/br205757

1

除非它是系统 DLL 或通过系统路径定位,否则您需要确保将您的 DLL 复制到与您的 Metro 应用程序部署在同一文件夹中。

我通过将本地 DLL 添加到我的 Metro 应用程序项目中来解决问题,确保 Build Action 设置为 Content,并且 Copy to Output Directory 设置为 Copy AlwaysCopy if Newer


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接