从dll导出包含std :: objects(vector,map等)的类 [英] Exporting classes containing std:: objects (vector, map, etc) from a dll

查看:657
本文介绍了从dll导出包含std :: objects(vector,map等)的类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从包含std :: vectors和std :: strings等对象的DLL导出类 - 通过以下方式将整个类声明为dll导出:

I'm trying to export classes from a DLL that contain objects such as std::vectors and std::strings - the whole class is declared as dll export through:

    class DLL_EXPORT FontManager
{

问题是对于复杂类型的成员我得到这个警告:

The problem is that for members of the complex types I get this warning:


警告C4251:'FontManager :: m__fonts':class'std: :map< _Kty,_Ty>'需要使用dll接口来使用'FontManager'类型的客户端

[
_Kty = std :: string,
_Ty = tFontInfoRef
]

warning C4251: 'FontManager::m__fonts' : class 'std::map<_Kty,_Ty>' needs to have dll-interface to be used by clients of class 'FontManager' with [ _Kty=std::string, _Ty=tFontInfoRef ]

我可以通过在他们之前放置以下前面的类声明来删除一些警告虽然我没有更改成员变量本身的类型:

I'm able to remove some of the warnings by putting the following forward class declaration before them even though I'm not changing the type of the member variables themselves:

template class DLL_EXPORT std::allocator<tCharGlyphProviderRef>;
template class DLL_EXPORT std::vector<tCharGlyphProviderRef,std::allocator<tCharGlyphProviderRef> >;
std::vector<tCharGlyphProviderRef> m_glyphProviders;

看起来像前面的声明注入DLL_EXPORT,当成员被编译,但它是否安全?当客户端编译此标题并在其侧面使用std容器时,它是否真的可以更改任何内容?它会使所有将来使用这样的容器DLL_EXPORT(也可能不是内联?)?这是否真的解决了警告试图警告的问题?

Looks like the forward declaration "injects" the DLL_EXPORT for when the member is compiled but is it safe? Does it realy change anything when the client compiles this header and uses the std container on his side? Will it make all future uses of such a container DLL_EXPORT (and possibly not inline?)? And does it really solve the problem that the warning tries to warn about?

这个警告是什么我应该担心,还是最好在范围内禁用它的这些构造?客户端和dll将始终使用同一组库和编译器构建,而那些只是标题类...

Is this warning anything I should be worried about or would it be best to disable it in the scope of these constructs? The clients and the dll will always be built using the same set of libraries and compilers and those are header only classes...

我正在使用Visual Studio 2003标准STD图书馆。

I'm using Visual Studio 2003 with the standard STD library.

----更新----

---- Update ----

我想要定位你更多的是,虽然我看到的答案是一般的,在这里我们正在谈论std容器和类型(如std :: string) - 也许这个问题真的是:

I'd like to target you more though as I see the answers are general and here we're talking about std containers and types (such as std::string) - maybe the question really is:

我们可以通过同一个库头禁用对客户端和dll可用的标准容器和类型的警告,就像处理int或其他内置类型一样对待它们? (这似乎在我身边正常工作。)如果是这样,我们可以这样做的条件呢?

Can we disable the warning for standard containers and types available to both the client and the dll through the same library headers and treat them just as we'd treat an int or any other built-in type? (It does seem to work correctly on my side.) If so would should be the conditions under which we can do this?

或者应该禁止使用这些容器至少要非常谨慎,以确保没有赋值运算符,复制构造函数等将被内联到dll客户端中。

Or should maybe using such containers be prohibited or at least ultra care taken to make sure no assignment operators, copy constructors etc will get inlined into the dll client?

一般来说,我想知道你是否设计一个具有这样的对象(例如使用它们将东西返回给客户端作为返回值类型)的dll接口是一个好主意,为什么 - 我想要一个高级接口来实现这个功能?也许最好的解决方案是Neil Butterworth建议的 - 创建一个静态库?

In general I'd like to know if you feel designing a dll interface having such objects (and for example using them to return stuff to the client as return value types) is a good idea or not and why - I'd like to have a "high level" interface to this functionality... maybe the best solution is what Neil Butterworth suggested - creating a static library?

推荐答案

当你从客户端,需要提供一个DLL接口。
DLL-interface表示编译器在DLL本身中创建函数并使其可导入。

When you touch a member in your class from the client, you need to provide a DLL-interface. A DLL-interface means, that the compiler creates the function in the DLL itself and makes it importable.

因为编译器不知道哪些方法是由DLL_EXPORTED类的客户端使用,它必须强制所有方法都是dll导出的。
它必须执行所有可以由客户端访问的成员都必须dll导出他们的功能。当编译器警告您未导出的方法,并且客户端的链接器发送错误时,会发生这种情况。

Because the compiler doesn't know which methods are used by the clients of a DLL_EXPORTED class it must enforce that all methods are dll-exported. It must enforce that all members which can be accessed by clients must dll-export their functions too. This happens when the compiler is warning you of methods not exported and the linker of the client sending errors.

不是每个成员都必须使用dll-export标记。私人会员无法接触客户。在这里,您可以忽略/禁用警告(请注意编译器生成的dtor / ctors)。

Not every member must be marked with with dll-export, e.g. private members not touchable by clients. Here you can ignore/disable the warnings (beware of compiler generated dtor/ctors).

否则,成员必须导出其方法。
使用DLL_EXPORT向前声明它们不会导出这些类的方法。您必须将其编译单元中的相关类别标记为DLL_EXPORT。

Otherwise the members must export their methods. Forward declaring them with DLL_EXPORT does not export the methods of these classes. You have to mark the according classes in their compilation-unit as DLL_EXPORT.

它归结为...(对于不是dll可导出的成员)

What it boils down to ... (for not dll-exportable members)


  1. 如果您有成员不能/不能被客户端使用,请关闭警告。

  1. If you have members which aren't/can't be used by clients, switch off the warning.

如果您有成员必须由客户端使用,请创建一个dll-export包装器或创建间接方法。

If you have members which must be used by clients, create a dll-export wrapper or create indirection methods.

要减少外部可见成员的数量,请使用 PIMPL成语等方法。 p>

To cut down the count of externally visible members, use approaches such as the PIMPL idiom.







template class DLL_EXPORT std::allocator<tCharGlyphProviderRef>;

这确实创建了当前编译单元中模板专业化的实例化。所以这样在dll中创建std :: allocator的方法,并导出相应的方法。这对于具体的类不起作用,因为这只是模板类的实例化。

This does create an instantiation of the template specialization in the current compilation unit. So this creates the methods of std::allocator in the dll and exports the corresponding methods. This does not work for concrete classes as this is only an instantiation of template classes.

这篇关于从dll导出包含std :: objects(vector,map等)的类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆