简而言之,我有一个VC ++ dll,它连接到MS Access(.mdb)文件并读取数据。两个Perl脚本将加载相同的DLL并读取相同的数据。唯一的区别是perl脚本位于不同的文件夹中(比如文件夹'A'和文件夹'B')。
当文件夹'A'中的Perl脚本加载DLL并打开数据库连接时,它就会成功。
当文件夹'B'中的Perl脚本加载DLL并打开数据库连接时,它无法打开连接(发生异常)。
当我查看事件查看器时,我找到了以下日志。
Faulting application name: perl.exe, version: 5.12.1.1201, time stamp: 0x4bed097d
Faulting module name: msjet40.dll, version: 4.0.9756.0, time stamp: 0x49246e48
Exception code: 0xc0000005
Fault offset: 0x0007128f
Faulting process id: 0x1634
Faulting application start time: 0x01cecb4f0080e109
Faulting application path: C:\Perl512\Perl\bin\perl.exe
Faulting module path: C:\Windows\SysWOW64\msjet40.dll
Report Id: 42f2cbc9-3742-11e3-91cd-001b2109685d
操作系统:Windows 7 Professional 64位
MS Office: MS Office 2007标准版(没有MS Access完整版,只安装了Access Runtime Engine)
连接字符串: strConnection = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\"D:\\Documents\\LocalFile.mdb\"";
注意: DLL将始终连接到相同的MS Access文件并使用相同的连接字符串
由于文件夹“A”中的脚本能够连接到数据库,因此我认为连接字符串中没有问题。 关于根本原因的任何想法/线索?
如果您需要任何其他详细信息,请与我们联系。提前谢谢!
答案 0 :(得分:1)
我找到了根本原因:)。错误消息“未指定的错误”虽然不是很有用..
也许,我没有给出足够的信息来思考这里的根本原因。无论如何,我将在这里留下根本原因,以便指出某人的方向可能会有所帮助。
使用Perl XS将DLL链接到Perl。在调用DLL函数之前,Perl XS为函数的输出变量分配了大量的内存(大约1.76 GB)。
正在运行的程序已经使用了一些内存。因此,总内存使用量约为1.9 GB。当DLL尝试打开与MS Access数据库的连接时,Msjet40.dll可能已经耗尽内存。 'OutOfMemoryException'可能是合适的。但是我得到了“未指明的错误”。
我是如何调试的?
(我知道,这很有趣:))最初我怀疑MS Access文件。所以,我试着Compact and Repair the MS Access file。显然,它没有用。
然后我尝试将OleDbConnection更改为OdbcConnection。至少,这显示“系统资源超出”例外。
所以我开始VMMap来分析内存使用情况。在那里,我看到在Heap中分配了大量的内存。
因此找到了根本原因。
为什么文件夹“A”perl脚本没有问题?
文件夹“A”perl脚本在调用DLL函数之前使用较少的内存。所以,它不会超过the memory limit (2 GB) of Windows 32-bit process。
答案 1 :(得分:0)
来自support.microsoft.com
如果您连接到Microsoft Access数据库,然后在一个进程中创建超过64个连接,您可能会收到以下错误消息之一:
In Microsoft Visual Studio .NET: Unspecified error
Steps to reproduce the behavior...
使用 关闭 方法:
Connection属性实际上返回对活动数据库的ActiveX数据对象(ADO)连接的副本的引用。因此, 应用Close方法 或者无论如何试图通过Connection对象的方法或属性 来改变连接都没有影响 < / strong>在Microsoft Access用于保存与当前数据库的实时连接的实际连接对象上。