2009. 10. 23. 22:38

warning C4251

1. 현상

  

이 글은 예전 GPG 스터디 포럼에 jst0808 님이 올리신 주제와 그에 대한 답글들입니다. 원본(Ezboard)은 "STL질문여..!"입니다.


제목: STL질문여..!
글쓴이: jst0808 , 글쓴때: 6/5/01 11:26:59 am
class 를 하나 만들었어여.
그안에 STL vector 를사용한 기능이 있는데..
그냥 static library로 쓸때는 암 문제 없이 돌아 갔어어여.
근데 dll 로 만드니깐.

warning C4251: 'STL_MyVec' : class 'std::vector<struct MyVec,class std::allocator<struct MyVec> >' needs to have dll-interface to be used by clients of class 'MyClass'

이런 워닝이 뜨데여. 기능은 별문제 없이 돌아가는데..
좀 찜찜해서리..
갈켜 주세여.

제목: 도움말에 따르면..

글쓴이: gryu , 글쓴때: 6/5/01 11:52:10 pm


STL_MyVec의 기반 클래스를 선언할 때 앞에 __declspec(dllexport) 를 붙이지 않았기 때문이라고 합니다.

STL과 특별한 관련이 있는 것 같지는 않구요. 일반적으로 클래스의 멤버 함수를 익스포트할 때 고려해야 하는 문제인 것 같은데.. 다른 분이 좀 더 자세히 이야기해 주시길...


/*************************
as simple as possible,
but not simpler
*************************/




제목: 걍 무시해버리세요..

글쓴이: zho , 글쓴때: 6/6/01 9:46:18 am

__declspec(dllexport) 로 선언되지 않은 클래스를 사용할 때 나타나는 경고입니다. 주로 MFC 클래스들을 사용할때 나타납니다.
만약 mfc 를 사용하지 않는다면 겉으로 드러나는 클래스는 전부 __declspec(dllexport) 를 사용하시구여.
#pragma warning(disable: 4251)
로 경고를 막아버리시면 경고에 대한 스트레스를 받지 않을 겁니다.
stl 을 사용하다보면 몇가지 경고가 나오는데, 대부분 위의 방법으로 무시해버리실 수 있습니다.

제목: 에구 첨 써보는데... ^^
글쓴이: midihana , 글쓴때: 6/8/01 3:03:27 am
하하.. MFC 코드에도 보면 맨 위에 항상..
#pragma warning(disable : 4251)
#pragma warning(disable : 4786)

요 두놈이 꼭 따라다니더군여....
STL 쓰시면서 젤 많이 만나는 경고일겁니다..
저두 STL 많이 쓰는 편인데..
이젠 아예 코드 맨 위에다가 버릇처럼 써넣습니다.. ^^

그럼 즐프하세요.. ^^

[출처] [펌] [stl] #pragma warning(disable : 4786)|작성자 오서비



DLL제작시 warning C4251: 에 대한 대처 PDF 문서 인용.

 

#include<vector>
#if !defined(DLLEXPORT_EXPORTS)
# define DLLEXPORT_API __declspec(dllexport)
#else
# define DLLEXPORT_API __declspec(dllimport)
#endif
class DLLEXPORT_API CDLLexport
{
public:
std::vector<char> vs;
};

 

warning C4251: 'vs' : class 'std::vector< char,class
std::allocator<char> >' needs to have dll-interface to be used by
clients of class 'CDLLexport'

 

이 경고는 클래스 CDLLexport에서 사용된 vs라는 개체의 클래스가
DLL 인터페이스를 가져야 한다고 말해주고 있다. 즉 이 경고에 따르면 m_strUpdateIgnore는 DLL에 해당
하는 인터페이스가 없기 때문에 외부에서 사용할 수 없다는 뜻이다. 분명 클래스를 DLL 인터페이스로
지정하였는데 어째서 UpdateIgnore::m_strUpdateIgnore는 문제가 발생하는 것일까? 일반적인 클래스나 함수, 개체를
DLL 인터페이스로 지정하는 것은 위와 같은 선언이면 충분하지만, 템플릿을 DLL 인터페이스로 지정하
기 위해서는 좀더 복잡한 과정이 필요하기 때문이다.
템플릿은 DLL 인터페이스로 지정되기 전에 먼저 템플릿을 인스턴스화하고, 이 인스턴스가 DLL 인터페
이스를 갖는다고 지정해야 한다. 앞의 예를 다음과 같이 수정해 보자.
#include<vector>
#if !defined(DLLEXPORT_EXPORTS)
# define DLLEXPORT_API __declspec(dllexport)
# define DLLEXPORT_TEMPLATE
#else
# define DLLEXPORT_API __declspec(dllimport)
# define DLLEXPORT_TEMPLATE extern
#endif
DLLEXPORT_TEMPLATE template class DLLEXPORT_API std::vector<char>;
class DLLEXPORT_API CDLLexport
{
public:
std::vector<char> vs;
};
다시 컴파일해 보자. 자, C4251은 사라졌다. 먼저 사용할 컨테이너 vector의 완전한 인터페이스를 인
스턴스화하고, DLL 인터페이스를 지정함으로써 더 이상 경고가 발생하지 않는다. 여기서 사용된 키워
드 extern(DLLEXPORT_TEMPLATE)은 이 파일이 DLL용으로 컴파일될 때 템플릿 클래스를 명시적으
로 인스턴스화할 것을 명령하는 역할을 한다.
이런 방법을 사용한다고 해도 DLL에서 컨테이너를 export하는 것은 vector를 제외하면 불가능하다.
인스턴스화와 동시에 인터페이스를 지정하는 도중 체인이 발생하여 더 이상 인스턴스화를 진행할 수 없
기 때문이다.


출처 : http://blog.naver.com/wwforever80/60043796212
댓글만 남기고 허락 없이 퍼왔어요 - -;