1

简而言之,我有一个 VC++ dll,它连接到一个 MS Access (.mdb) 文件并读取数据。两个 Perl 脚本将加载相同的 DLL 并读取相同的数据。唯一的区别是 perl 脚本位于不同的文件夹中(比如文件夹“A”和文件夹“B”)。

  1. 当文件夹“A”中的 Perl 脚本加载 DLL 并打开数据库连接时,它是成功的。

  2. 当文件夹“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 专业版 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”中的脚本能够连接到数据库,我认为连接字符串没有问题。关于根本原因的任何想法/线索?

如果您需要任何其他详细信息,请告诉我。提前致谢!

4

2 回答 2

2

我找到了根本原因:)。错误消息“未指定的错误”虽然不是很有帮助..

也许,我没有提供足够的信息来思考这里的根本原因。无论如何,我将把根本原因留在这里,以便为某人指出方向可能会有所帮助。

DLL 通过使用 Perl XS 链接到 Perl。在调用 DLL 函数之前,Perl XS 为函数的输出变量分配了大量的内存(几乎 1.76 GB)。

正在运行的程序已经使用了一些内存。因此,总内存使用量约为 1.9 GB。当 DLL 试图打开与 MS Access 数据库的连接时,Msjet40.dll 可能内存不足。' OutOfMemoryException ' 可能是合适的。但我得到了“未指定的错误”。

我是如何调试的?

  1. (我知道,这很有趣:))最初我对 MS Access 文件持怀疑态度。所以,我尝试压缩和修复 MS Access 文件。显然,它没有用。

  2. 然后我尝试将OleDbConnection更改为OdbcConnection。至少,这显示了“系统资源超出”异常。

  3. 所以我启动了VMMap来分析内存使用情况。在那里我看到在堆中分配了大量的内存。

从而找到了根本原因。

为什么文件夹“A”perl 脚本没有问题?

在调用 DLL 函数之前,文件夹“A”perl 脚本使用较少的内存。因此,它不会超过Windows 32 位进程的内存限制(2 GB)

于 2013-10-19T10:57:48.223 回答
1

来自 support.microsoft.com

如果您连接到 Microsoft Access 数据库,然后在一个进程中创建超过 64 个连接,您可能会收到以下错误消息之一:

In Microsoft Visual Studio .NET:    Unspecified error

重现行为的步骤...


关于使用Close方法:

Connection 属性实际上返回对活动数据库的 ActiveX 数据对象 (ADO) 连接副本的引用。因此,应用 Close 方法或尝试通过 Connection 对象的方法或属性更改连接不会影响Microsoft Access 用于保持与当前数据库的实时连接的实际连接对象。

来自微软开发中心

于 2016-07-16T03:03:47.043 回答