2010-01-21 4 views
6

많은 공유 라이브러리에 걸쳐 상당히 큰 크기의 프로젝트를 진행하고 있습니다. 또한 STL, Boost 및 자체 템플릿 클래스 및 함수에 크게 의존합니다. 많은 내 보낸 클래스에는 템플리트 구성원이 있으며 내 보낸 함수에는 템플리트 매개 변수가 있습니다. 내가 비주얼 스튜디오 (2008 년과 2010 년 모두)에서 컴파일 할 때공유 객체/DLL에서 템플릿 클래스 및 함수 사용

#if defined(_MSC_VER) && defined(_DLL) 
    // Microsoft 
    #define EXPORT __declspec(dllexport) 
    #define IMPORT __declspec(dllimport) 
#elif defined(_GCC) 
    // GCC 
    #define EXPORT __attribute__((visibility("default"))) 
    #define IMPORT 
#else 
    // do nothing and hope for the best at link time 
    #define EXPORT 
    #define IMPORT 
#endif 

#ifdef _CORE_COMPILATION 
#define PUBLIC_CORE EXPORT 
#define EXTERNAL_CORE 
#else 
#define PUBLIC_CORE IMPORT 
#define EXTERNAL_CORE extern 
#endif 

#include <deque> 

// force exporting of templates 
EXTERNAL_CORE template class PUBLIC_CORE std::allocator<int>; 
EXTERNAL_CORE template class PUBLIC_CORE std::deque<int, std::allocator<int> >; 

class PUBLIC_CORE MyObject 
{ 
private: 
    std::deque<int> m_deque; 
}; 

SO, 내 문제는, 나는 다음과 같은 얻을 : 여기

내가 라이브러리 수출을 어떻게의 제거 다운 예입니다 경고 :

경고 C4251 : '표준 : _ Deque_val < _Ty, _Alloc> :: _ Almap' : 클래스 '표준 : : 할당 < _Ty>' 에 DLL-간이 필요 얼굴은 클래스 의 고객의 표준 : _ Deque_val < _Ty, _Alloc> '내가이 std::allocator<int>를 수출하지 않았 음을 의미하는 것으로 보인다

사용할 수 있습니다. 클래스의 표준 : 양단 큐 < _Ty> ':

경고 C4251 :'을 MyObject : m_deque '그리고 내 수출이

EXTERNAL_CORE template class PUBLIC_CORE std::allocator<int>; 
EXTERNAL_CORE template class PUBLIC_CORE std::deque<int, std::allocator<int> >; 

을 포함하지 않는 때문에 잘못된 것 아니에요 경고를 산출 클래스의 클라이언트가 사용하는 DLL 인터페이스를 가질 필요 '을 MyObject'

내가 생각할 수있는 유일한 방법입니다 _Ty 일에 대한 경고가 e std::allocator은 어쨌든 int이 아니지만, std::deque<int>std::allocator<int>으로 논리적으로 할당되기 때문에 별다른 표시가없는 것 같습니다.

소비하는 응용 프로그램은 클래스를 잘 사용할 수 있지만이 경고를 무시해서는 안된다고 생각합니다. 리눅스에서 g ++로 컴파일 할 때 오류는 발생하지 않습니다 (그렇다고해서 제대로 작동하는 것은 아닙니다). g ++가 자동으로 MSVC가 할 수없는 일을하고 있습니까? 저는 Linux에서 GCC, Windows에서 OSX 및 MSVC에 LLVM을 타겟팅하고 있었지만 잠재적으로 Windows 개발을 위해 MinGW로 이동할 수 있으므로 MSVC를 포기하는 것이 문제가되지는 않습니다 (이 점이 너무 큰 불편 함을 입증하는 경우) .

+1

_ 그 경고를 보완 해 주셔서 감사합니다. – xtofl

+0

이 항목은 http://stackoverflow.com/q/5661738/417197과 중복 되었습니까 (또는 이와 유사합니까?)? –

답변

3

알다시피, 내보내기 파일의 템플릿은 사실 컴파일러에서 '필요하다고 생각하는 모든 것을 채울 수있는 권한'입니다.

즉, 컴파일러 A로 헤더 파일을 컴파일하면 컴파일러 B와 완전히 다른 deque<int>을 인스턴스화 할 수 있습니다. 일부 멤버의 순서는 일부 멤버 변수의 실제 유형이나 변경 될 수 있습니다.

그리고 컴파일러가 경고합니다.

편집 : 같은 컴파일러에 의해 컴파일 할 때

그래서 공유 라이브러리는 잘 함께 작동 설명에 어떤 영향을 addes.그것들을 함께 사용하기를 원한다면, 모든 클라이언트 코드가 (동일한 stl 구현을 사용하여) 동일한 선언을 보게하거나, 템플릿을 API에 추가하는 것으로 되돌아 가도록 할 수 있습니다.

+1

+1 : 동일한 컴파일러 일뿐만 아니라 동일한 컴파일러의 동일한 버전입니다. VS 2008과 VS 2008 SP1은 잠재적으로 서로 다른 STL 유형 및 STL 유형을 구현할 수 있습니다. –

+0

필자는'EXTERNAL_CORE 템플릿 클래스 PUBLIC_CORE std :: deque > '과 같은 명령문은 컴파일러가 컴파일러가 std :: deque의 원본 컴파일러 구현을 사용하도록 강제하기위한 것이 었습니다. __dllimport. 컨테이너는 내가 정말로 문제가있는 유일한 것입니다 (복잡하지 않은 것들의 내보내기가 잘 작동하는 것처럼 보입니다). –

+0

@Travis : 대상 컴파일러가 std :: deque의 원래 구현을 어떻게 알 수 있습니까? –