关于WOSA/XFS中SP程序报无效地址的错误
2007-08-19 14:07
483 查看
[align=center]关于WOSA/XFS中SP程序报无效地址的错误[/align]
[align=center][/align]
[align=center]刘永胜 2006年于广州[/align]
[align=center][/align]
[align=center][/align]
如果深入接触过符合WOSA/XFS规范的软件,会有幸看到有时候软件报以下错误:“invalid virtual base addr., GetLastError: 487”。
当定位错误时,会发现是XFS_SUPP.DLL程序报出来的错。
如果不知道原因,解决这个问题将会花费一些时间,甚至即使解决了也不知道具体原因。因为有很多人问过该问题,所以将其写下来,以有利于需要的人,节省他们的时间。
用regedit程序打开Windows注册表,如果是2.0版本的XFS ,在路径HKEY_CLASSES_ROOT/WOSA/XFS_ROOT/XFS_MANAGER下面,如果是3.0版本的XFS ,在路径HKEY_LOCAL_MACHINE/SOFTWARE/XFS/XFS_MANAGER下面,有几项注册表内容和这个有关,分别是:
ShareMapAddr=6BC00000
ShareFileName=c:/xfs_supp.sys
ShareFileSize=5242880
解决上面提到的错误有以下方法(改完后可能要重启机器才生效):
一、将ShareMapAddr的值改变,默认一般该值是6BC00000,把值改大点或改小点,比如改成7BC00000。
二、将ShareMapAddr项删除,让其自动定位地址。
三、修改软件中关于装载DLL的基地址信息,如果是调用LoadLibrary动态装载,则考虑下各个DLL的装载顺序问题。
四、编译时将静态链接的DLL基地址进行修改,避免操作系统加载程序时的重定位基地址,导致使用到了ShareMapAddr以上的地址空间。
下面详细讲一下为什么会出现这个错误,这样可以做到知其所以然。
因为SP是基于DLL导出接口的形式,所以存在一个多进程共享内存的问题。两个EXE调用同一个设备的SP,因为SP的DLL会被加载到每个EXE进程中,导致它们之间的内存并不能共享,从而导致信息不同步。
为了处理这个问题,在WOSA/XFS的内存分配函数WFMAllocateBuffer中的第二个参数ulFlags是比较重要的,如果在程序中使用WFMAllocateBuffer,则XFS Manager会根据ulFlags标志进行不同的处理。
如果ulFlags标志设置为0,则使用进程内部的堆内存。此时XFS Manager只是简单的调用HeapAlloc、HeapFree系列Heap处理函数来分配内存,我们都知道这种内存只存在本EXE进程的内部,另外一个进程正常是看不到该内存的,从而内存是私有的,无法共享。
如果设置值为WFS_MEM_SHARE,则会使用XFS Manager里面的共享内存。在Windows平台下面,本质上的进程之间共享内存,大多是基于内存映射文件的方式来实现的。XFS Manager在启动的时候,会创建一个内存映射文件,名字就是上面注册表提到的ShareFileName=c:/xfs_supp.sys,该文件会在XFS Manager第一次被调用的时候创建,被映射到ShareMapAddr=6BC00000项所定的基地址,并且向高位地址端保留ShareFileSize=5242880字节的内存范围,是给内存共享使用的,以后访问该块内存,在所有调用该SP DLL的EXE进程里面的该地址段内容将都是一样的,都被映射到ShareFileName=c:/xfs_supp.sys内存映射文件中。如果不存在ShareMapAddr=6BC00000项,则由操作系统来自动分配一个可用的空间,但这个空间的基地址每次装载是可能发生变化的。
对于内存映射文件的原理请参考相关资料,这里不多讲。我们显然会想到一个问题就是存在XFS Manager会在ShareMapAddr的基地址处将ShareFileName映射到进程内存空间失败的情况。最大的可能是该地址中的某一段被其他模块占用了。如果这样,XFS Manager则就会报“invalid virtual base addr., GetLastError: 487”,因为XFS Manager不能够将内存映射文件映射到规定的地址空间。
好了,知道原因了,就可以理解上面提到的几种解决方法,以后就不会因为这种问题而烦恼了。
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1425764
[align=center][/align]
[align=center]刘永胜 2006年于广州[/align]
[align=center][/align]
[align=center][/align]
如果深入接触过符合WOSA/XFS规范的软件,会有幸看到有时候软件报以下错误:“invalid virtual base addr., GetLastError: 487”。
当定位错误时,会发现是XFS_SUPP.DLL程序报出来的错。
如果不知道原因,解决这个问题将会花费一些时间,甚至即使解决了也不知道具体原因。因为有很多人问过该问题,所以将其写下来,以有利于需要的人,节省他们的时间。
用regedit程序打开Windows注册表,如果是2.0版本的XFS ,在路径HKEY_CLASSES_ROOT/WOSA/XFS_ROOT/XFS_MANAGER下面,如果是3.0版本的XFS ,在路径HKEY_LOCAL_MACHINE/SOFTWARE/XFS/XFS_MANAGER下面,有几项注册表内容和这个有关,分别是:
ShareMapAddr=6BC00000
ShareFileName=c:/xfs_supp.sys
ShareFileSize=5242880
解决上面提到的错误有以下方法(改完后可能要重启机器才生效):
一、将ShareMapAddr的值改变,默认一般该值是6BC00000,把值改大点或改小点,比如改成7BC00000。
二、将ShareMapAddr项删除,让其自动定位地址。
三、修改软件中关于装载DLL的基地址信息,如果是调用LoadLibrary动态装载,则考虑下各个DLL的装载顺序问题。
四、编译时将静态链接的DLL基地址进行修改,避免操作系统加载程序时的重定位基地址,导致使用到了ShareMapAddr以上的地址空间。
下面详细讲一下为什么会出现这个错误,这样可以做到知其所以然。
因为SP是基于DLL导出接口的形式,所以存在一个多进程共享内存的问题。两个EXE调用同一个设备的SP,因为SP的DLL会被加载到每个EXE进程中,导致它们之间的内存并不能共享,从而导致信息不同步。
为了处理这个问题,在WOSA/XFS的内存分配函数WFMAllocateBuffer中的第二个参数ulFlags是比较重要的,如果在程序中使用WFMAllocateBuffer,则XFS Manager会根据ulFlags标志进行不同的处理。
如果ulFlags标志设置为0,则使用进程内部的堆内存。此时XFS Manager只是简单的调用HeapAlloc、HeapFree系列Heap处理函数来分配内存,我们都知道这种内存只存在本EXE进程的内部,另外一个进程正常是看不到该内存的,从而内存是私有的,无法共享。
如果设置值为WFS_MEM_SHARE,则会使用XFS Manager里面的共享内存。在Windows平台下面,本质上的进程之间共享内存,大多是基于内存映射文件的方式来实现的。XFS Manager在启动的时候,会创建一个内存映射文件,名字就是上面注册表提到的ShareFileName=c:/xfs_supp.sys,该文件会在XFS Manager第一次被调用的时候创建,被映射到ShareMapAddr=6BC00000项所定的基地址,并且向高位地址端保留ShareFileSize=5242880字节的内存范围,是给内存共享使用的,以后访问该块内存,在所有调用该SP DLL的EXE进程里面的该地址段内容将都是一样的,都被映射到ShareFileName=c:/xfs_supp.sys内存映射文件中。如果不存在ShareMapAddr=6BC00000项,则由操作系统来自动分配一个可用的空间,但这个空间的基地址每次装载是可能发生变化的。
对于内存映射文件的原理请参考相关资料,这里不多讲。我们显然会想到一个问题就是存在XFS Manager会在ShareMapAddr的基地址处将ShareFileName映射到进程内存空间失败的情况。最大的可能是该地址中的某一段被其他模块占用了。如果这样,XFS Manager则就会报“invalid virtual base addr., GetLastError: 487”,因为XFS Manager不能够将内存映射文件映射到规定的地址空间。
好了,知道原因了,就可以理解上面提到的几种解决方法,以后就不会因为这种问题而烦恼了。
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1425764
相关文章推荐
- 关于 SQL 2005 安装程序无法获取ASPNET账户的系统账户信息 错误解决办法
- SQLServer错误:过程 sp_addextendedproperty,第 xxx 行对象无效。'dbo.xxx.xxx' 不允许有扩展属性,或对象不存在。
- QT程序编译无错误,运行时出现访问地址冲突
- 关于WIN10 edge浏览器报错 找不到DNS地址 错误代码:INET_E_RESOURCE_NOT_FOUND 的解决方法
- 关于Android系统调试程序经常出现的错误解决方法(一)
- 关于java第一个简单程序错误原因
- 快速开发关于SP程序
- 关于MySql中命令行输入密码界面,输入密码无效登陆不了的错误解决
- 关于Symbian的"程序已经关闭"错误
- 关于Symbian的"程序已经关闭"错误
- 关于Symbian的"程序已经关闭"错误
- 关于Asp程序的Server.CreateObject错误解决方法
- 关于VS2010出现错误:程序数据库管理器不匹配;请检查安装 解决方案
- Debug Assertion Failed! 错误解决 (关于文件文件写入程序)
- Android程序开发中关于设置全屏无效问题
- 关于asp程序的Server.CreateObject错误解决方法
- SharePoint运行错误—“公共语言运行时检测到无效的程序”
- 关于Visual Studio 2013 编译 multi-byte character set MFC程序出现 MSB8031 错误的解决办法
- 关于导致 N70 下载jad安装程序, 出现 "授权失败" 的错误
- 关于Visual Studio 2013 编译 multi-byte character set MFC程序出现 MSB8031 错误的解决办法