如何在 stl 模板中使用导出类 (__declspec(dllexport))?

发布于 2024-10-04 02:15:01 字数 351 浏览 7 评论 0原文

我正在使用导出的类

class __declspec(dllexport) myclass  
{  
private:  
template __declspec(dllexport) class std::map<myclass*,int>;    
std::map<myclass*,int>m_map;  
//something  
};    

当我这样做时,我收到警告 C4251,提示 m_map:class 'std::map<_Kty,_Ty>'需要有 dll 接口供 myclass 类的客户端使用。
关于如何解决这个问题有什么想法吗?
阿图尔

I am using an exported class

class __declspec(dllexport) myclass  
{  
private:  
template __declspec(dllexport) class std::map<myclass*,int>;    
std::map<myclass*,int>m_map;  
//something  
};    

When I do this, I get a warning C4251 saying m_map:class 'std::map<_Kty,_Ty>' needs to have dll-interface to be used by clients of class myclass.
Any ideas about how i can resolve this ?
Atul

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

挽袖吟 2024-10-11 02:15:01

您不应该在使用 DLL 的代码将要使用的头文件中使用 __declspec(dllexport),因为它们需要使用 __declspec(dllimport)。

因此,您应该创建一个宏,如果设置了特定的其他定义,则使用 dllexport;如果未设置,则使用 dllimport。

在某个公共标头中:

#ifdef EXPORTING_FOO
#define FOO_API __declspec(dllexport)
#else
#define FOO_API __declspec(dllimport)
#endif

您可以实例化模板:

extern template class FOO_API Templ<MyClass, int >;

在包含的标头中。注意这里的外部。
在一个编译单元内声明相同的内容,但没有 extern 且没有 FOO_API,因此:

template class Templ<MyClass, int >;

这将意味着使用您的库的代码不会实例化模板,而是使用您的库中的模板。当模板具有虚拟成员时,这特别有用。

如果模板是来自标准库或 boost 的模板,则使用您的代码必须使用与您的版本相同的版本,否则可能会出现严重问题。

鉴于在您自己的示例中它出现在私有区域中,表明您希望将其从库的界面中重构出来。理想情况下,您的库应该只公开公共方法和成员,而不是前向声明。为了使类不可复制和不可分配,私有复制构造函数和赋值很好 - 它们并不是真正实现的一部分,它们是类接口的一部分(你是说你不能复制或分配它们)。

You should not be using __declspec(dllexport) into the header files that code using your DLL will be using, as they need to be using __declspec(dllimport).

Therefore you should create a macro that uses dllexport if a particular other define is set, and dllimport if it is not.

In a common header somewhere:

#ifdef EXPORTING_FOO
#define FOO_API __declspec(dllexport)
#else
#define FOO_API __declspec(dllimport)
#endif

You can instantiate a template:

extern template class FOO_API Templ<MyClass, int >;

within an included header. Note the extern here.
Within one compilation unit declare the same but without the extern and without the FOO_API, thus:

template class Templ<MyClass, int >;

This will mean that the code using your library will not instantiate the template but will be using the one in your library. This is particularly useful when the template has virtual members.

If the template is one from the standard library or boost, the code using yours will have to be using the same version as yours or there could be a serious problem.

Given that in your own example it appears in the private area suggests you want to refactor it out of the interface for your library. Ideally your library should only expose public methods and members other than forward declarations. Private copy-constructors and assignments in order to make a class non-copyable and non-assignable are fine - they are not really part of the implementation they are part of the interface of your class (you are saying that you cannot copy or assign them).

仅此而已 2024-10-11 02:15:01

您无法导出包含未导出成员的类。一个可能的解决方案是使用 Pimpl 惯用法。对于 Pimpl,用户不知道类的成员。所以不需要导出stl类。要进一步阅读有关 pimpl 的内容,请检查以下内容:
http://c2.com/cgi/wiki?PimplIdiomhttp://www.gamedev.net/reference/articles/article1794.asp

示例:

myclass.h:

class __declspec(dllexport) myclass
{
public:
    myclass();
    virtual ~myclass();
private:
    myclass(const myclass& other) {}
    myclass& operator=(const myclass& rhs) {return *this;}
    myclassImpl* m_Pimpl;
};

myclass .cpp:

#include "myclass.h"
#include "myclassImpl.h"


myclass::myclass()
    :m_Pimpl(new myclassImpl())
{}

myclass::~myclass() {
    delete m_Pimpl;
}

myclassImpl.h:

class myclassImpl {
private:
    std::map<myclass*,int>m_map;
};

You can not export a class with members that are not exported. A possible solution would be using the Pimpl idiom. With Pimpl the members of the class are not known to the user. So no stl classes need to be exported. For further reading about pimpl check the following:
http://c2.com/cgi/wiki?PimplIdiom or http://www.gamedev.net/reference/articles/article1794.asp

Example:

myclass.h:

class __declspec(dllexport) myclass
{
public:
    myclass();
    virtual ~myclass();
private:
    myclass(const myclass& other) {}
    myclass& operator=(const myclass& rhs) {return *this;}
    myclassImpl* m_Pimpl;
};

myclass.cpp:

#include "myclass.h"
#include "myclassImpl.h"


myclass::myclass()
    :m_Pimpl(new myclassImpl())
{}

myclass::~myclass() {
    delete m_Pimpl;
}

myclassImpl.h:

class myclassImpl {
private:
    std::map<myclass*,int>m_map;
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文