(编辑)如何在Windows中导出模板专业化,并在cpp文件中声明源
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(编辑)如何在Windows中导出模板专业化,并在cpp文件中声明源相关的知识,希望对你有一定的参考价值。
编辑此问题已被大量修改
我试图从cpp文件中定义的dll导出模板特化(纯粹是为了导出模板)。
基于在头文件中使用dllimport / export的第一次尝试(“First Attempt”)结果在编译和运行时都有效,但它产生了C4661警告(没有为显式模板实例化请求提供合适的定义)。这是我第一次提出这个问题。然而@AnT答案显示我的错误,我试图通过“第二次尝试”来纠正这一点,但这也会导致警告。
第一次尝试
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;
}
我在dll中有一段测试代码输出一个值。
TEST.CPP
#include "foo.h"
int readValue()
{
foo<int> test;
return test.value();
}
第二次尝试
关于@ AnT关于标准的说明,在cpp中实例化工作,但我留下了另一个问题(授予这是所有VC-fu)。将代码更改为以下以确保实例化在cpp中完成(按标准并使dll导出工作),我得到一个警告C4251:'bar :: value':类'foo'需要有dll-interface才能结构'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
我相信bar结构在使用__declspec(dllexport)在cpp中实例化之前实例化foo模板。除了“这是疯了,这都是错的,为什么你这样做”,有没有办法绕过这个或者这只是windows dll导入/导出的特点,它是什么?
语言规范说
14.7.2显式实例化 9定义类模板特化的显式实例化定义显式实例化类模板特化,并且是仅在实例化时定义的那些成员的显式实例化定义。
在您的情况下,您的显式实例化定义不会为foo<int>::value()
提供显式实例化定义,因为在显式实例化时,该成员尚未定义。
C4661的目的是告知您该问题。 MSVC很有可能对dllexport
-ed实体应用特殊处理,这最终使您的代码能够正确链接。但从语言的角度来看问题是存在的。
以上是关于(编辑)如何在Windows中导出模板专业化,并在cpp文件中声明源的主要内容,如果未能解决你的问题,请参考以下文章