我有一个使用第三方原生C dll的应用程序。在具有.Net 4的Windows 7计算机上,一切运行良好,但在Windows XP(SP3)和.Net 4上运行失败。
我在Windows XP计算机上遇到以下异常。
未处理的异常:System.AccessViolationException:尝试读取或写入 受保护的记忆这通常表明其他内存已损坏。
当我调试时,
CacheInteropTest.exe中0x10069e1d的第一次机会异常:0xC0000005:访问冲突读取位置0x00000000。
这是我的简化测试应用程序代码:
public unsafe class Program
{
[STAThread]
static void Main(string[] args)
{
var status = CacheEnd();
Console.ReadKey(true);
}
[SuppressUnmanagedCodeSecurity]
[DllImport("cachet.dll", EntryPoint = "#24", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
internal extern static int CacheEnd();
}
我在Windows XP(SP3)32位上编译了上述程序,并将其复制到Windows 7计算机并运行,它没有给出任何异常。第三方dll与可执行文件位于同一文件夹中。
我发现许多与AccessViolationException相关的问题的回复,特别是这个 AccessViolationException in P/Invoke call非常接近。 另一个网站有关于PInvoke和内存相关问题的概述 http://dotnetdebug.net/2006/04/17/pinvoke-and-memory-related-issues/但在这种情况下对我没有帮助。
第三方dll是数据库内核,提供多线程数据库访问(每个线程维护一个连接)。在API的文档中,提到dll必须是静态链接的,并且在Windows XP上使用这个dll的C ++应用程序也能很好地工作。
我认为问题在于本机dll的实现,但为什么它在Windows 7上运行良好?
任何人都知道Windows XP上可能出现什么问题?
供应商提供的本机功能原型类型是
extern int CFPROTOD(CacheEnd,(void));
所以我猜这个问题与调用约定无关。
答案 0 :(得分:1)
问题是由于Windows的限制。 API的静态链接要求来自供应商已知的此限制。 http://support.microsoft.com/kb/118816解释了Windows中的问题。看起来这已在Win 7中修复