从Finalize中删除非托管对象会引发AccessViolationException 我用C++ + CLI编写了一个非托管C++项目的包装库。目标是向C#应用程序公开此库。这是我到目前为止所拥有的 #pragma once #include "Settings.h" #include "Settings/SettingsPrivate.h" public ref class Settings { public: Settings(); virtual ~Settings(); protected: !Settings(); public: unsigned char GetModel(int iNumber); private: CSettings* m_pSettings; };

从Finalize中删除非托管对象会引发AccessViolationException 我用C++ + CLI编写了一个非托管C++项目的包装库。目标是向C#应用程序公开此库。这是我到目前为止所拥有的 #pragma once #include "Settings.h" #include "Settings/SettingsPrivate.h" public ref class Settings { public: Settings(); virtual ~Settings(); protected: !Settings(); public: unsigned char GetModel(int iNumber); private: CSettings* m_pSettings; };,c#,visual-studio-2008,c++-cli,C#,Visual Studio 2008,C++ Cli,代码在我编写的测试应用程序中执行良好。函数调用成功。问题是,当GC完成这个对象时,它会抛出一个异常 Wrapper.dll中发生类型为“System.AccessViolationException”的未处理异常 其他信息:尝试读取或写入受保护内存。这通常表示其他内存已损坏 我看不出抛出此异常的任何明显原因。我试图通过从C#应用程序中调用Dispose来显式地处理对象。它仍然抛出相同的异常 以下是测试应用程序: using System; using System.Collections.Gen

代码在我编写的测试应用程序中执行良好。函数调用成功。问题是,当GC完成这个对象时,它会抛出一个异常

Wrapper.dll中发生类型为“System.AccessViolationException”的未处理异常

其他信息:尝试读取或写入受保护内存。这通常表示其他内存已损坏

我看不出抛出此异常的任何明显原因。我试图通过从C#应用程序中调用Dispose来显式地处理对象。它仍然抛出相同的异常

以下是测试应用程序:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WrapperTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Settings settings = new Settings();
            byte b = settings.GetModel(0);

            settings.Dispose();

            return;
        }
    }
}

有人会指出我做错了什么吗???

您应该启用更详细的堆调试功能。我测试了你的代码,对我来说没有失败。我不得不使用malloc/free而不是new/delete,因为您没有定义CSettings,但是效果应该是一样的

我添加这一点是为了确保我有足够的堆搅动器,如果它们有任何损坏,就会触发失败

unsigned char Settings::GetModel(int iNumber)
{   
    for(int i=0; i < iNumber; i++)
        free(malloc(1024));
    return iNumber;
}
无符号字符设置::GetModel(int iNumber)
{   
for(int i=0;i

对我来说,你的代码没有失败。您应该查看一些编译设置,是否链接到外部库进行CSettings?如果是这样,您需要确保CRT是相同的版本,等等。您还知道必须使用DLL运行时的not/MT或/MTd之一

这是一个项目配置错误。代码实际上在发布模式下运行良好

在调试模式下,我在一些发布DLL中进行了链接,而我本应该对调试库进行静态链接。为什么这会导致内存损坏我还没有调查,但它解决了这个问题


否则,上面发布的代码是正确的。

无需重新编写,看不出问题所在。我假设问题出在设置Sprivate中,我猜是堆损坏。如果您在调试器中启用“第一次机会中断AV”(“调试->异常->Win32异常->访问冲突”;您可能希望在“工具->选项->调试”中禁用“仅我的代码”),访问的是什么(您还需要在C#项目中启用本机调试,因为我假设您是使用它启动的)“从这段代码中没有什么东西会让我觉得是错的。@汉斯:你昨晚的评论让我走上了解决问题的正确道路。如果你发布一个答案,我会给你这个问题的分数。继续,发布你的答案,展示真实情况,并将其标记为答案。每个编写非托管代码的人都可以学到一些东西。”调试堆损坏问题。这在稍后提醒了我DLLMain问题。您不能抢占运行时(即,在CLR启动之前不要运行代码)。
unsigned char Settings::GetModel(int iNumber)
{   
    for(int i=0; i < iNumber; i++)
        free(malloc(1024));
    return iNumber;
}