stl을 DLL제작시 문제점..warning C4251: 에 대한 대처
원문링크 : http://blog.naver.com/wwforever80/60043796212
#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를 제외하면 불가능하다.
인스턴스화와 동시에 인터페이스를 지정하는 도중 체인이 발생하여 더 이상 인스턴스화를 진행할 수 없
기 때문이다.
'Study > C++' 카테고리의 다른 글
문자열 비교할때 대소문자 구분없이 하기. (0) | 2010.12.03 |
---|---|
dllimport, dllexport (0) | 2010.11.15 |
RTTI (0) | 2010.11.07 |
safe memcpy (0) | 2010.11.02 |
pointer to member function의 크기? (0) | 2010.10.24 |