将嵌入式Dll从eVC移植到VS2008导致找不到DLL

时间:2014-07-25 14:48:46

标签: memory compiler-construction embedded global-variables porting

我正在尝试将非托管C ++ Dll从一个嵌入式设备移植到另一个嵌入式设备,并且面临一些奇怪的问题,我认为这些问题必须与内存管理和/或编译器有关。我没有发布很多代码,但描述了我尝试的内容,因为我尝试了太多不同的东西来发布所有代码,我认为问题必须在更深层次的内容。

第一个设备运行WinCE 5.0,使用嵌入式Visual C ++ 4.0编译。 第二个设备运行Windows Embedded Compact 7(为简单起见,我将其称为WinCE 7),并使用VS2008进行编译。两种设备都有自己的SDK,专为电路板设计。

在第一台设备上,Dll正在运行,没有任何问题,但在第二台设备上使用新的SDK编译的Dll无效。在第二台设备上进行C#applikation我尝试使用PInvoke来访问dll,但是在调试模式下的PInvoke线上收到了错误消息:

  

无法找到PInvoke DLL NAME.dll

After some research我了解到这个错误可能有不同的原因:

  1. 缺少您正在调用的本机库的依赖项。
  2. 本地人被编译为错误的子系统(即桌面,而不是CE)
  3. 为错误的处理器(即x86而非ARM)编译本机程序集
  4. 没有足够的虚拟内存供DLL加载。
  5. 我用peinfo来检查dll。所有依赖项都在设备上找到,它是为WinCE 7编译的,处理器类型是正确的。 (如果没有,我会感到惊讶,使用正确的SDK)所以还有4号:没有足够的虚拟内存。但WinCE5仅限32MB虚拟内存并运行,而WinCE7最高可达2GB? 所以我开始尝试一些方法来缩小错误,并告诉你我的结果。

    首先,我为第一台设备编译了我的dll并尝试在第二台设备上使用它。令人惊讶的是.net应用程序可以找到并PInvoke这个。但是Dll中的一些功能似乎没有运行,所以我想我必须使用正确的SDK。但是对于这两个dll都有正确的代码,我知道出口必须是正确的。我知道这两个编译器使用不同的c ++名称修改样式,所以这也不是问题。

    接下来,我在VS2008上编写了一个简单的c ++应用程序,使用新的SDK从那里加载Dll。在第一个设备上,应用程序以这种方式运行,但现在在我的远程显示器上运行第二个设备时,我收到错误消息:

      

    无法导入库NAME.dll!程序将退出。

    至少现在我知道它与.net和PInvoke无关。但是我进一步使用VS2008制作了一个简单的新dll,新的SDK和ne .net应用程序能够PInvoke它。所以代码中必定有一些东西不喜欢被加载。 : - /

    经过几个小时的搜索,我意识到系统并不像一些全局变量。我知道全局变量很糟糕,如果他们不在那里我会很高兴,但我还没有启动代码,多年来他们在我处理它之前越来越多,所以他们会很难现在擦除。

    这些全局变量是类的实例。其中一些似乎很糟糕,其他一些似乎没问题。令人困惑的是,他们都是课程的实例,我不知道为什么有好的和坏的。当我注释掉坏全局变量时,应用程序能够PInvoke Dll。其中一个糟糕的全局变量足以使应用程序找不到Dll。

    为什么使用带有WinCE 7的VS2008但不使用带有WinCE 5的eVC4.0?全局变量有什么问题?我怎么解决这个问题?至多相同的代码应该适用于两个编译器,但首先我需要一些想法,第二个编译器有什么问题。

1 个答案:

答案 0 :(得分:0)

我找到了解决我的Dll加载问题的方法。这两个系统在#pragma pack上有不同的行为。所以最终在加载dll导致dll崩溃时出现了错位。由于全局变量是在dll的加载过程中,因此错误消息没有说明错位,但标准"无法找到PInvoke DLL"。