편집 CPP 파일에 선언 된 소스와, Windows에서 템플릿 전문화를 수출 dll을하는 (편집) cpp 파일에 정의되어 있습니다 (순수하게 템플리트를 내보낼 목적으로).어떻게이 질문은 많이</p> <p>I는 DLL에서 템플릿 전문화를 수출하려고 수정되었습니다
머리글에서 dllimport/export를 사용한 첫 번째 시도 ("첫 번째 시도")가 컴파일 및 런타임에서 작동하는 것으로 판명되었지만 C4661 경고가 발생했습니다 (명시 적 템플릿 인스턴스화 요청에 적합한 정의가 제공되지 않음).). 이것이 내가 처음에 질문 한 내용입니다. 그러나 @AnT 응답은 내 실수를 보여 주었고 "Second Attempt"로이를 수정하려고 시도했으나 경고도 나타납니다.
첫번째 시도
foo.h
#ifndef _foo_h_ //header guard
#define _foo_h_
#ifdef EXAMPLE_FOO_EXPORTS
#define EXAMPLE_FOO_EXPORT __declspec(dllexport)
#define EXAMPLE_FOO_EXTERN
#else
#define EXAMPLE_FOO_EXPORT __declspec(dllimport)
#define EXAMPLE_FOO_EXTERN extern
#endif
template<typename _Type>
class foo
{
public:
_Type value();
};
EXAMPLE_FOO_EXTERN template class EXAMPLE_FOO_EXPORT foo<int>;
#endif//_foo_h_
foo.cpp에
#include "foo.h"
template<typename _Type>
_Type foo<_Type>::value()
{
return (_Type)1;
}
I 출력 할 DLL 테스트 코드의 일부 값을 갖는다.
Test.cpp에
#include "foo.h"
int readValue()
{
foo<int> test;
return test.value();
}
두 번째 시도
, 표준의 개미의 참고 @ 떨어져가는 CPP의 작품 인스턴스하지만이 부여 된 또 다른 문제 (왼쪽하고 모든 VC입니다 -부). 아래의 코드를 변경하여 인스턴스화가 cpp (표준 및 dll 내보내기 작동)에서 수행되는지 확인하기 위해 C4251 경고가 표시됩니다. 'bar :: value': 클래스 'foo'는 dll 인터페이스가 있어야합니다. struct bar의 클라이언트가 사용합니다.
foo.h
#ifndef _foo_h_ //header guard
#define _foo_h_
#ifdef EXAMPLE_FOO_EXPORTS
#define EXAMPLE_FOO_EXPORT __declspec(dllexport)
#define EXAMPLE_FOO_EXTERN
#else
#define EXAMPLE_FOO_EXPORT __declspec(dllimport)
#define EXAMPLE_FOO_EXTERN extern
#endif
template<typename _Type>
class foo
{
public:
_Type value();
};
typedef foo<int> fooInt;
#ifndef EXAMPLE_FOO_EXPORTS
extern template class __declspec(dllimport) foo<int>;
#endif
struct EXAMPLE_FOO_EXPORT bar
{
fooInt value;
};
#endif//_foo_h_
foo.cpp에
#include "foo.h"
template<typename _Type>
_Type foo<_Type>::value()
{
return (_Type)1;
}
#ifdef EXAMPLE_FOO_EXPORTS
template class __declspec(dllexport) foo<int>;
#endif
나는 그것이 __declspec (dllexport)와 cpp에있는 인스턴스화하기 전에 바 구조체 foo는 템플릿을 인스턴스화 믿습니다. "이것은 미친 짓이야,이 모든 잘못이고 왜 이러는거야?", 이것에 대한 방법이 있습니까 아니면이 dll 가져 오기/내보내기의 단지 독특한 무엇입니까 그리고 그것이 무엇입니까?
헤더 파일에서 명시적인 인스턴스화 정의를 수행하는 이유는 무엇입니까? 이것은 일어날 대기 ODR 위반입니다. – AnT
** C4661 경고 **에 대해 설명하지 않았습니다. 다른 컴파일러 (예 : [GCC] (http://gcc.gnu.org/),'g ++ -Wall -Wextra -g')를 사용해보십시오. 그러면 또 다른 * 경고가 나옵니다. 하지만 실제로는 소스 코드를 개선하는 것이 좋습니다. –
C4661 : 명시 적 템플릿 인스턴스화 요청에 적절한 정의가 제공되지 않습니다. 그리고 이것은 순전히 dll 수입/수출 문제입니다. @AnT가 언급 한대로 인스턴스화를 cpp 파일로 이동하는 것은 올바른 방법이며 (대부분의 다른 컴파일러도이를 만족해야합니다). 내가 실수로 만든 이유는 Windows dll에 필요한 dllexport 요구 사항을 해결하려고하기 때문입니다. – Krazer