2008-10-17 1 views
5

MFC 앱의 크고 오래된 코드 기반을 만들고 있습니다. 이 코드는 많은 개발자들에 의해 시간이 지남에 따라 작업되었으며 결과적으로 새로운 코드로 할당 실패의 가능성을 다루는 코드 전체에서 세 가지 다른 방법이 있습니다.MFC 프로젝트에 연결된 mfc가없는 C++ 정적 라이브러리가 bad_alloc 또는 CMemoryException *을 throw합니까?

첫 번째 방법은 new 결과에 대해 NULL을 테스트하는 것입니다. nothrownew.obj를 사용하지 않기 때문에 명확하게 정리해야하는 오류입니다.

두 번째는 CMemoryException *을 catch하는 것입니다 (예, C++ 예외는 컴파일러에서 사용 가능합니다). 내가 이해 한 바로는 MFC가 표준 연산자 new를 재정의하고 대신이 것을 던졌습니다. 이 두 번째 방법은 MFC 응용 프로그램 자체에서 올바른지 상당히 확신합니다. MFC는 이상한 CMemoryException 버젼의 버젼을 새롭게 오버라이드 (override)합니다.

마지막은 C++에 능숙하지만 MFC 프로그래머는 필요하지 않은 사람들로부터 온 것입니다. 그들은 const std :: bad_alloc &을 잡습니다.

내가 정말로 모르는 부분은 응용 프로그램에 연결된 정적 라이브러리를 기대해야한다는 것입니다. 이것은 bad_alloc 생명체를 사용하는 대다수의 코드입니다. 이 라이브러리가 MFC 또는 ATL로 컴파일되지 않았고 표준 C++로만 작성되었다고 가정하면 bad_alloc을 잡을 수 있습니까? 아니면 그들이 링크하는 응용 프로그램에서 MFC가 글로벌 new 연산자로 감염되어 잘못된 할당 깔깔에서 깨끗하게 실패하려고 시도합니까?

답변이 있다면 어떻게 작동하는지 설명하거나 올바른 참조로 알려 주시면 설명해 주시겠습니까?

답변

3

연결될 정적 라이브러리에 대한 컴파일 옵션에 따라 달라질 수 있습니다 응용 프로그램.

라이브러리가 ++ 런타임 정적 표준 C를 사용하는 구성으로 컴파일 된 경우 나 실행 시간 ++ 표준 C에서 operator new을 기대 호출합니다.

라이브러리가 런타임에게 ++ 다음 DLL 이러한 기능의 해상도가 프로그램로드까지 지연되고 operator new의 MFC 교체로 해결해야 할 표준 C를 사용하는 구성으로 컴파일합니다.

유용 할 수있는 핸들 할당 오류에 관한 허브 스터 article에 대한 링크도 포함되었습니다.

+0

고마워요! 우리는 표준 C++ 런타임을 DLL로 링크합니다. 이는 모든 사람을위한 MFC 예외를 의미합니다. 불행히도,이 응용 프로그램의 주요 대상 중 하나는 가상 메모리가없는 시스템이므로 할당 검사가 필요합니다. –

+0

기호로 컴파일 할 수 있다면 연산자 new 호출로 들어가는 것이 좋을 것입니다. 디버거는 어떤 구현이 호출되는지 확실히 증명해야합니다. 그것이 목표 플랫폼에 도움이 될지 확실하지 않은 경우 .. – Henk

+0

심볼은 아무런 문제가되지 않습니다. CMemoryException *이 던져지고 있다는 것을 확실하게 보여줍니다. 그것은 일을 복잡하게 만들지 만, 실제로 진행되고있는 일을 알고있는 것이 좋습니다. 다시 한 번 감사드립니다! –

1

축하해 - 당신은 우리 모두를 난처하게 만들었습니다. :-)

이론적으로 MFC가 글로벌 new 함수에 과부하를 제공하는 경우 프로그램에서 모두 코드로 사용해야합니다. 그러나 정적 라이브러리가 그것에 대해 알지 못해 컴파일 되었기 때문에, 그렇게 말할 수는 없습니다.

내가 제안 할 수있는 최선의 방법은 테스트 코드를 작성하는 것입니다. (필자는 앞으로 몇 시간 동안 내 Windows 시스템에 액세스 할 수 없거나 스스로 대답을 줄 것입니다.)

+0

이렇게하면 동료가 어려워 질 것이며 아무도 좋은 방법을 찾을 수 없습니다 처음부터 새로운 것을 과부하시키지 않고 새로운 것을 실패하게 만듭니다. Arg :) –

0

AfxSetNewHandler(_PNH pfnNewHandler)으로 MFC 던지기 동작을 변경하고 자신의 NewHandler 함수에 대한 포인터를 제공 할 수 있습니다. 이 함수는 std::bad_alloc 예외를 throw합니다. 그러나 이제 MFC 프로그램 파트는 std::bad_alloc을 잡는 데 문제가 있습니다.

1

VC2010에서 일부 MFC 코드 연구를 수행했습니다. 다음은 몇 가지 사실입니다.

  1. 는 MFC는 "_simpleMemoryException"라는 글로벌 CMemoryException 인스턴스에 포인터를 발생 (도 AfxThrowMemoryException() 참조)
  2. 그것은 그 m_bAutoDelete 거짓 인 CException이다.

아이디어 : 그것은 가능한 C++ 변경하는 경우 - 전용 정적 라이브러리를 루트 네임 스페이스에 class CException; 및/또는 class CMemoryException;를 선언 전달할 수 있습니다.

블록이 std::bad_alloc-catch 인 각 위치에 catch (CMemoryException* pEx) {...} 및/또는 catch (CException* pEx) {...}의 캐치 블록을 추가하십시오. catch 된 포인터는 전역 개체에 대한 포인터이기 때문에 pEx->Delete();을 호출 할 필요가 없습니다.

이렇게하면 C++ 전용 정적 라이브러리에 afx.h 또는 MFC에 대한 링크가 포함될 필요가 없습니다. 난 VC2010에서 그것을 시도하고 잘 작동합니다. (RTTI가 활성화 된 경우에만 AfxSetNewHandler를 사용하는 MFC-NewHandler를 기본값 인 MFC-NewHandler AfxNewHandler으로 변경하지 않은 경우에만)

관련 문제