문제

나는 대략적인 모습을 보이는 정적 메소드가있는 클래스가 있습니다.

class X {
    static float getFloat(MyBase& obj) {
        return obj.value();  // MyBase::value() is virtual
    }
};

나는 mybase를 서브 클래스하는 Myderived 인스턴스와 함께 그것을 부릅니다.

MyDerived d;
float f = X::getFloat(d);

x가 포함 된 OBJ 파일을 실행 파일에 연결하면 모든 것이 예상대로 작동합니다. 3.14를 얻을 것으로 예상되면 얻을 수 있습니다.

.lib에 x.obj 파일과 링크가 포함 된 .lib를 만들면 깨집니다. getfloat ()에게 전화하면 돌아오고 있습니다. -1.#ind00. 여기에 무엇이 잘못되었는지 알려주는 센티넬 값의 일부 유형입니까?

직접 OBJ가 아닌 lib에서 링크 할 때 다른 것이 있습니까?

컴파일러 경고 나 오류가 없습니다.

편집하다:
Windows XP Pro SP3에서 Visual Studio 2005를 사용하고 있습니다. 오래된 파일을 연결하지 않도록하기 위해 value () 메소드를 새로운 value2 () 메소드로 클로닝하여 대신 호출했습니다. 행동은 동일했습니다.

#2 편집 :
따라서 디버거로 통화를 추적하면 내 값 () 메소드로 전혀 들어 가지 않는다는 것을 알게되었습니다. 대신 다른 (관련이없는) 방법으로 들어가고 있습니다. 이것은 내 vtable이 손상되었다고 생각하게 만듭니다. 내가보고있는 행동은 다른 문제의 부작용이어야한다고 생각합니다.


해결되었다! (블라드 덕분에)
내가 게시 한 코드에서 명백하지는 않았지만 ODR (One Definition Rule)을 위반 한 것으로 나타났습니다. 이것 시각적 C ++ Guys의 훌륭한 기사로 문제를 설명하고 추적하는 한 가지 방법입니다. 그만큼 /d1reportsingLeclassLayout 컴파일러 플래그는 환상적인 학습 도구입니다.

MyBase의 클래스 레이아웃을 버렸고 두 개의 다른 프로젝트에서 MyDerived를 획득했을 때 호출 코드와 라이브러리 코드의 차이점을 발견했습니다. 내가 일부가 있었다는 것이 밝혀졌습니다 #ifdef 내 헤더 파일의 블록 및 해당 #정의하다 진술은 메인 프로젝트의 선행 헤더에 있었지만 하위 프로젝트 (라이브러리)에는 없었습니다. 내가 사전 처리기 매크로가 얼마나 악한 지 언급 했습니까?

어쨌든, 나는 다른 사람에게 도움이 될 수 있기 때문에이 내용 만 게시하고 있습니다. 이 질문 나에게도 매우 도움이되었습니다.

도움이 되었습니까?

해결책

이 문제는 LIB와 실행 파일이 컴파일되면 발생합니다. 다른 정의 MyDerived 수업 (즉, 다른 버전의 .h/.hh/.hpp 선언하는 파일 MyDerived. 프로젝트를 완전히 깨끗하게하고 재건하십시오. 이것을 제외하고 다른 컴파일러 옵션 ~할 수 있었다 책임이 없지만 책임이 없습니다.

처음부터 모든 것을 재건 한 후 문제가 지속되면 더미를 인스턴스화하여 못 박 힙니다. MyDerived 내부의 물체 getFloat, 도서관에서. 디버거를 사용하여 비교하십시오 vtable 더미의 MyDerived (도서관에 인스턴스화) 및 vtableMyDerived 객체 참조는 매개 변수 (실행 파일에 인스턴스화)로 전달되었습니다.

다른 팁

lib는 단지 컨테이너이기 때문에 두 경우 모두 동일한 .obj 파일을 연결하는 경우 Brian이 말하지 말아야 할 것처럼 차이가되지 않아야합니다.

볼만한 한 가지는 MyBase의 정의를 변경하면 라이브러리를 사용하여 라이브러리와 코드를 다시 컴파일해야합니다. 예를 들어, 값 메소드 전에 MyBase에 새 가상 메소드를 추가하면 v-table 값 오프셋이 다르기 때문에 라이브러리가 엉망이됩니다.

차이가 없어야합니다. 포함하는 .H 파일이 정확히 연결되는 .lib에 해당하는지 확인하십시오. 이전 .lib 파일에 링크 할 수 있다고 생각합니다.

.lib 파일을 명시 적으로 지정하는 대신 Visual Studio를 사용하는 경우 프로젝트를 마우스 오른쪽 버튼으로 클릭하고 의존성을 .lib 프로젝트로 설정하십시오. 이렇게하면 올바른 .lib 파일을 사용하는지 확인합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top