【问题标题】:Can't find PInvoke DLL error in Windows Mobile在 Windows Mobile 中找不到 PInvoke DLL 错误
【发布时间】:2010-11-30 04:14:42
【问题描述】:

我在获取基本方案以在 windows mobile 5.0 模拟器上工作时遇到了很多麻烦。我有一个最终调用本机代码的 winforms 应用程序。部署工作正常,所有本机 DLL 都复制到与 winforms .exe 相同的文件夹中。我还使用远程文件查看器工具验证了这种情况。

但是,当我启动我的应用程序时,它总是失败并显示“找不到 PInvoke dll -- System.MissingMethodException”错误(当调用本机代码时,DllImport 属性变得无用)。我知道本机 dll 与可执行文件位于同一文件夹中。我还应该做什么?

我正在使用 VS 2008。

【问题讨论】:

  • 2 快速 cmets:1) 我第一次在 exe 的文件夹中没有任何本机 DLL。所以这个例外至少在当时是有意义的。现在确保一切都已部署,我怎么能再次遇到 same 异常? 2)我尝试按照这篇文章中的描述设置日志记录:blogs.msdn.com/netcfteam/archive/2005/07/24/442609.aspx 我曾经使用远程注册表编辑器来执行此操作,但无济于事。根本没有创建日志文件!这么多基本的东西怎么会出错?

标签: .net windows-mobile compact-framework pinvoke emulation


【解决方案1】:

为了扩展 Jared 的回答,在 CF 中 P/Invoking 时获得 MissingMethodException 的四个常见原因:

  1. 您缺少要调用的本机库的依赖项
  2. 为错误的子系统(即桌面,而不是 CE)编译了本机程序集
  3. 为错误的处理器(即 x86 而不是 ARM)编译了本机程序集
  4. 您没有足够的虚拟内存来加载 DLL。

您是否验证过 DLL 入口点未使用 dumpbin 之类的内容进行修饰?

【讨论】:

  • 另外,如果您希望本机 DLL 与调用 exe 位于同一目录中,请确保该 exe 实际部署在同一目录中。
【解决方案2】:

鉴于错误消息,通常存在以下两个问题之一

  1. 找不到 DLL。通过查看执行目录和PATH环境变量找到DLL
  2. 在 DLL 中找不到函数。您是否检查过以确保 DLL 的声明和定义都是 extern "C" 并标记为 __declspec(dllexport)

此外,完整性检查是为了确保 DLL 名称拼写正确且缺少 .dll 后缀。

【讨论】:

  • 嗨,贾里德,感谢您的回复。 1)我确定本机dll与执行应用程序位于同一目录中。实际上有 2 个本地 dll。我评论了一个调用,现在另一个抛出 same 异常 2) 检查——我也为 Win32 平台编译了相同的代码库,它在那里工作得很好 dll 名称是拼写的正确,它确实有 .dll 后缀(这不是你的意思吗?)
  • 您是否也知道为什么我无法正确设置它:blogs.msdn.com/netcfteam/archive/2005/07/24/442609.aspx 我使用远程注册表编辑器输入了所有 reqd 键,但仍然没有创建日志文件。今天一定是万事大吉!
  • 仅供参考,无论是否使用“dll”后缀,它都可以正常工作,尽管您应该在传入的确切字符串中保持一致(我使用 const):danielmoth.com/Blog/2007/12/be-consistent-with-dllimports.html
  • 迄今为止的所有建议都是我过去用来解决这些问题的。不过,我有两件事要尝试。 1. 要启用 .NETCF 日志记录,请尝试在最后一个键和键值下设置 DWORD 值。我忘记了哪种组合对我有用,但我记得它让我感到困惑,仍然如此 - 例如 [HKLM\Software\Microsoft\.NETCompactFramework\Diagnostics\Logging] "Enabled" = 1。 2. 尝试使用本地 DLL 的发布编译版本.我们有一些 DLL 拒绝 P/Invoke 他们的调试版本。从未解决它,可能是构建开关。
【解决方案3】:

您的问题是由于 WM5 内存管理是废话。 DLL 从插槽顶部到底部加载,而应用程序从底部到顶部加载。如果您的应用和 DLL 之间没有足够的空间,您将收到“无法 pinvoke”错误。

WM5 分配 32 个 32Mb 的插槽供应用程序运行。

WM5 每次为 dll 分配内存时,它至少使用 64Kb 块,所以如果你的 DLL 是 32K,它将占用 64k,如果你的 DLL 占用 68k,那么 WM5 将分配 2x64Kb — 128Kb。

当 WM5 加载所需的 DLL 时,它总是会在预先加载的应用程序的底部地址加载,即如果应用程序 1 加载了 2×30kb 的 DLL,第一个将在地址 0 到 64k 处加载,第二个从64 到 128,那么您的应用将从 128kb 加载其 DLL,而不是 0,即使您的应用运行到单独的插槽中也是如此。

为了使事情正常进行,您必须提前加载您的应用程序或从 Windows 启动文件夹中删除不需要的应用程序。

【讨论】:

  • 是的,但不是真的。对于本机 DLL 是正确的,但对于这个问题不是正确的。这个问题被标记为“compact-framework”,并且托管 DLL 不会在此内存模型下加载。它们作为内存映射文件加载,不占用 64k 虚拟内存块。 MSDN 有一个关于 Compact Framework 如何使用您可能感兴趣的内存的非常好的网络广播。
【解决方案4】:

您正在使用的 DLL 没有您正在调用的方法的定义。 所以发生异常.. 它编译得很好..仅在运行时出现问题.. 解决方案是您需要确保该定义是否存在于 DLL 中,否则您需要使用其他一些 dll。

【讨论】:

  • 方法可能不会出于导出目的而公开
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-01-22
  • 2012-07-25
  • 1970-01-01
  • 2018-07-22
  • 2012-03-13
  • 2014-04-26
  • 1970-01-01
相关资源
最近更新 更多