2011-04-01 3 views
1

언 매니지드 C++ 프로젝트에 C++/CLI를 사용하여 래퍼 라이브러리를 작성하고 있습니다. 목표는이 라이브러리를 C# 응용 프로그램에 표시하는 것입니다. 여기 내가 지금까지 가지고있는 것이있다. Finalize에서 관리되지 않는 객체를 삭제하면 AccessViolationException이 발생합니다.

#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가이 개체를 마무리 할 때 예외가 발생한다는 것입니다.

형 'System.AccessViolationException'처리되지 않은 예외 Wrapper.dll

부가 정보 발생 보호 된 메모리를 읽거나 쓰기 시도. 이것은 종종 다른 메모리가 손상되었다는 표시입니다.

이 예외가 발생하는 명백한 이유가 없습니다. 내 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; 
     } 
    } 
} 

누군가가 내가 잘못 것을 지적겠습니까?

+2

아니요 repro, 문제가 보이지 않습니다. 문제는 SettingsPrivate에 있다고 가정합니다. 힙 손상은 내가 추측 할 수 있습니다. –

+0

"Debug -> Exceptions -> Win32 Exceptions -> Access Violation"이라는 디버거에서 첫 번째 기회 AV를 중단 할 수있게 설정 한 경우 "도구 -> 옵션 -> 디버깅"에서 "내 코드 만 비활성화" 무엇이 액세스되고 있습니까 (C# 프로젝트에서 네이티브 디버깅을 사용하도록 설정해야합니다). 이 스 니펫에서 잘못된 것으로 나에게 뛰어 드는 것은 아무것도 없습니다. –

+0

@ 한스 : 지난 밤에 내 문제를 해결하기 위해 내 의견을 올바르게 짚어 보았습니다. 답변을 게시하면이 질문에 대한 크레딧을 줄 것입니다. – Nathanael

답변

2

프로젝트 구성 오류입니다. 코드는 실제로 릴리스 모드에서 정상적으로 실행되었습니다.

디버그 모드에서 디버그 라이브러리에 대해 정적으로 링크해야하는 경우 일부 릴리스 DLL에서 링크되었습니다. 이것이 왜 메모리 손상을 일으켰는지, 아직 조사하지는 않았지만 문제를 해결했습니다.

그렇지 않으면 위에 게시 된 코드가 정확합니다.

+0

이것은 나중에 DLLMain 문제를 떠올리게합니다. 런타임을 선점해서는 안됩니다 (예 :CLR get이 부트 스트랩되기 전에 코드가 실행되지 않음). – RandomNickName42

1

더 자세한 힙 디버깅 기능을 사용하도록 설정해야합니다. 나는 당신의 코드를 테스트했는데 실패하지 않았다. 필자는 CSettings를 정의하지 않았으므로 malloc/free 대신 new/delete를 사용해야했지만 효과는 동일해야합니다.

내가 손상을 유발할만큼 충분한 양의 힙이 있는지 확인하기 위해 추가했습니다.

unsigned char Settings::GetModel(int iNumber) 
{ 
    for(int i=0; i < iNumber; i++) 
     free(malloc(1024)); 
    return iNumber; 
} 

나를 위해 귀하의 코드는 실패없이 작동했습니다. 일부 컴파일 설정을 살펴보고 CSetting을위한 외부 라이브러리에 연결하고 있습니까? 그렇다면 CRT가 동일한 버전인지 확인해야합니다. 또한/MT 또는/MTd가 아닌 DLL 런타임 중 하나를 사용해야한다는 것도 알고 있습니다.

관련 문제