【发布时间】:2017-12-17 11:28:36
【问题描述】:
我正在使用 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;
};
#include "stdafx.h"
#include "Managed/Settings.h"
Settings::Settings()
{
// Pointer to unmanaged object
m_pSettings = new CSettings();
}
Settings::~Settings()
{
this->!Settings();
}
Settings::!Settings()
{
if (m_pSettings)
{
delete m_pSettings;
m_pSettings = NULL;
}
}
unsigned char Settings::GetModel(int iNumber)
{
return m_pSettingss->GetModel(iNumber);
}
代码在我编写的测试应用程序中执行良好。函数调用成功。问题是,当 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;
}
}
}
有人能指出我做错了什么吗?
【问题讨论】:
-
没有复制,看不出问题。我认为问题出在 SettingsPrivate,我猜是堆损坏。
-
如果您在调试器中启用第一次机会 AV 中断(“调试 -> 异常 -> Win32 异常 -> 访问冲突”;您可能希望在“工具 -> 中禁用“只是我的代码”选项 -> 调试”),正在访问什么(您还需要在 C# 项目中启用本机调试,因为我假设您正在使用它启动)?这个 sn-p 并没有让我觉得有什么不对。
-
@Hans:你昨晚的评论让我走上了解决问题的正确轨道。如果您发布答案,我会将这个问题归功于您。
-
继续,发布您的答案以显示实际情况并将其标记为答案。每个编写非托管代码的人都可以从调试堆损坏问题中学到一些东西。
标签: c# visual-studio-2008 c++-cli