오늘 내 dll과 실제 프로젝트에서 다른 CRT 설정 (MTd MDd)으로 인해 힙 손상이 발생했습니다. 내가 이상한 것을 발견 한 것은 응용 프로그램이 dll에서 소멸자를 가상으로 설정했을 때만 중단된다는 것입니다. 그 쉬운 설명이 있습니까? 나는 힙에없는 메모리를 해제 할 수 없지만, 소멸자를 가상이 아닌 것으로 정의 할 때 정확히 차이점은 무엇인가.CRT 가상 소멸자
일부 코드는
DLL을
#pragma once
class CTestClass
{
public:
_declspec(dllexport) CTestClass() {};
_declspec(dllexport) virtual ~CTestClass() {};
};
그리고 내 프로젝트
int main(int argc, char* argv[])
{
CTestClass *foo = new CTestClass;
delete foo; // Crashes if the destructor is virtual but works if it's not
}
또한 declspec을 * class * ('class _declspec (dllexport) CTestClass {...}')로 이동하고 멤버 별 declspecs를 제거하여 동일한 문제가 있습니까? 그냥 궁금해서. 그리고 호출 코드와 DLL은 동일한 CRT (디버그 또는 릴리스)를 사용해야하므로 고려해야 할 사항이 있습니다. 나는 혼합 모드가 지원되는지조차 모르겠다. (나는 그것이 있다고 생각하지 않는다). – WhozCraig
프로세스에 CRT 사본이 여러 개 있습니다. 그리고 v-table이 아니라 클래스 메소드 만 내보내십시오. 이 모든 것이 어떻게 상호 작용하여 코드를 폭파하는지 추론하는 것은 그다지 생산적이지 않습니다.가상 메소드를 사용하여 클래스를 내보내려면 전체 클래스를 내보내고 __declspec (dllexport)를 * class * 키워드 옆에 넣어야합니다. 그리고 객체를 생성하고 소멸시키는 데 하나의 할당자가 사용되는지 확인해야합니다./MD로 꾸준히 빌드하고 똑같은 컴파일러 버전을 사용하지 않는 한 보장하기가 어렵습니다. 모듈 경계를 넘어서 C++ 클래스를 노출하는 것은 위험합니다. –
당신이 옳다는 것은 적절합니다. 왜 그것이 작동하지 않는지를 알아 내더라도, 너무 많이 도와주지 않을 것입니다. 어쨌든 당신의 생각을 주셔서 감사합니다 :) – Poisonbox