gpt4 book ai didi

c++ - (编辑)如何使用 cpp 文件中声明的源在 Windows 中导出模板特化

转载 作者:行者123 更新时间:2023-11-30 05:06:39 25 4
gpt4 key购买 nike

编辑 这个问题已经被大量修改

我正在尝试从 cpp 文件中定义的 dll 中导出模板特化(纯粹是为了导出模板)。

基于在 header 中使用 dllimport/export 的第一次尝试(“第一次尝试”)结果证明在编译和运行时都有效,但是它产生了 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中有一段测试代码输出一个值。

测试.cpp

#include "foo.h"

int readValue()
{
foo<int> test;

return test.value();
}

第二次尝试

离开@AnT 的标准说明,在 cpp 中实例化工作,但我遇到了另一个问题(假设这都是 VC-fu)。将代码更改为以下以确保在 cpp 中完成实例化(根据标准并使 dll 导出工作),我收到警告 C4251: 'bar::value': class 'foo' needs to have dll-interface to be由 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

我相信 bar 结构在使用 __declspec(dllexport) 在 cpp 中实例化之前实例化了 foo 模板。除了“这太疯狂了,这都是错误的,你为什么要这样做”这一事实之外,有没有办法解决这个问题,或者这只是 Windows dll 导入/导出的一个特性,它就是这样吗?

最佳答案

语言规范说

14.7.2 Explicit instantiation
9 An explicit instantiation definition that names a class template specialization explicitly instantiates the class template specialization and is an explicit instantiation definition of only those members that have been defined at the point of instantiation.

在您的情况下,您的显式实例化定义foo<int>::value() 提供显式实例化定义。 ,因为在显式实例化时该成员尚未定义。

C4661 的目的是通知您有关该问题的信息。 MSVC 很可能对 dllexport 进行了特殊处理。 -ed 实体,这最终使您的代码能够正确链接。但从语言的角度来看,问题是存在的。

关于c++ - (编辑)如何使用 cpp 文件中声明的源在 Windows 中导出模板特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47824973/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com