std::vector 需要有 dll 接口才能由类 'X的客户端使用。警告

发布于 2024-10-01 17:54:28 字数 745 浏览 3 评论 0原文

我正在尝试使我的库可导出为 DLL,但对于使用 std::vector 的一个特定类,我收到了很多警告:

template <typename T>
class AGUI_CORE_DECLSPEC AguiEvent {
    typedef void (*AguiCallbackFptr)(T arg, AguiWidget* sender);
std::vector<AguiCallbackFptr> events;
public:
    void call(AguiWidget* sender, T arg) const;
    void addHandler(AguiCallbackFptr proc);
    void removeHandler(AguiCallbackFptr proc);
    void removeHandler();
    AguiEvent();
};

我收到如下警告:

警告 57 警告 C4251: 'AguiEvent::events' : 类 'std::向量<_Ty>'需要有 供客户端使用的 dll 接口 类“AguiEvent”

我试图找到如何正确执行此操作,但 MSDN 的文档非常仅限于 Windows,并且我需要它是跨平台的,以便它仅在 AGUI_CORE_DECLSPEC 实际上定义时才执行 MS 特定的操作。

我应该怎么做才能消除这些警告?

谢谢

I'm trying to make my library exportable as a DLL but I'm getting a lot of these warnings for one specific class that uses std::vector:

template <typename T>
class AGUI_CORE_DECLSPEC AguiEvent {
    typedef void (*AguiCallbackFptr)(T arg, AguiWidget* sender);
std::vector<AguiCallbackFptr> events;
public:
    void call(AguiWidget* sender, T arg) const;
    void addHandler(AguiCallbackFptr proc);
    void removeHandler(AguiCallbackFptr proc);
    void removeHandler();
    AguiEvent();
};

I get warnings like these:

Warning 57 warning C4251:
'AguiEvent::events' : class
'std::vector<_Ty>' needs to have
dll-interface to be used by clients of
class 'AguiEvent'

I tried to find how to do this properly but MSDN's documentation is very Windows Only, and I need this to be cross platform so that it only does MS specific stuff when AGUI_CORE_DECLSPEC is in fact defined.

What should I do to get rid of these warnings?

Thanks

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

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

发布评论

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

评论(4

仙女山的月亮 2024-10-08 17:54:28

从 DLL 导出是特定于平台的。您必须针对 Windows 修复此问题(基本上使用 declspec( dllexport/dllimport) 在实例化的类模板上)并将所需的代码封装在 Windows 特定的预处理器宏中。

我的经验是,在 Windows 上从 DLL 导出 STL 类充满了痛苦,通常我会尝试设计不需要这样做的接口。

Exporting from a DLL is platform-specific. You will have to fix this for Windows (basically use declspec(dllexport/dllimport) on the instantiated class template) and encapsulate the required code in your Windows-specific preprocessor macro.

My experience is that exporting STL classes from DLLs on Windows is fraught with pain, generally I try to design the interface such that this is not needed.

贪了杯 2024-10-08 17:54:28

一种修复方法是依赖 STL 结构的动态分配/解除分配。所以:

class EXPORTED ExportedClass
{
private:
    std::vector<int> *_integers;
public:
    ExportedClass()
    {
        _integers = new std::vector<int>();
    }
    ~ExportedClass()
    {
        delete _integers;
    }
};

不会给出任何警告,并且如果您分发的相同二进制文件(dll)必须与可能具有不同版本的 STL 的不同版本的编译器一起使用,它会更安全。通过这种方式,您可以 100% 保证 sizeof(ExportedClass) 始终相同。

One fix is relying on dynamic allocation/deallocation of the STL structures. So:

class EXPORTED ExportedClass
{
private:
    std::vector<int> *_integers;
public:
    ExportedClass()
    {
        _integers = new std::vector<int>();
    }
    ~ExportedClass()
    {
        delete _integers;
    }
};

won't give any warning and it's more safe in case you are distributing the same binary (the dll) that has to be used with different version of the compiler that may has different versions of the STL. In this way you have 100% guarantee that sizeof(ExportedClass) is always the same.

油焖大侠 2024-10-08 17:54:28

您可以只导出 dll 客户端需要访问的成员。为此,请从类声明中删除导出声明,并将其添加到要导出的每个单独的成员函数中。

编辑:

在您的情况下,您可能不应该尝试导出该类(忽略 AGUI_CORE_DECLSPEC),因为它是一个模板类。将标头中的所有方法作为内联提供,它将起作用。

如果您不希望这样做,某些编译器提供了一种特殊的方法来导出模板类。但您必须为此指定模板参数。

You could just export the members, which the dll-clients need to access. To do this remove the export declaration from the class declaration and add it to each individual member function you want to export.

EDIT:

In your case you should probably not try to export the class (leave out AGUI_CORE_DECLSPEC) since it is a template class. Provide all methods in your header as inline and it will work.

If you do not want this, some compilers provide a special way to export template classes. But you will have to specify the template parameter for this.

反目相谮 2024-10-08 17:54:28

处理此类特定于平台的内容的常用方法是尝试将所有特定于平台的设置限制为少数低级文件/类,然后使用 #defines 和 #ifdef/#ifndef 预处理器指令来添加/替换特定于平台的变体。

为了有效地实现这一点,您可能需要一个抽象层。例如,我在 20 世纪 90 年代开发的一个生产系统有一个“文件系统”库。这为应用程序和生产代码提供了一个通用接口,但必须依赖于一些特定于平台的文件。除了更容易编译和维护之外,它还更容易移植到新平台。新的文件硬件供应商或操作系统风格?只需将设置添加到包含文件中并相应地添加新指令即可。

The usual method of dealing with platform specific stuff like this is to try and restrict all platform specific settings to a handful of low level files/classes, and then use #defines and #ifdef/#ifndef preprocessor directives to add/replace platform specific variations.

To effectively implement this, you may need an abstraction layer. For example a production system I worked on in the 1990s had a "File System" library. This presented a common interface to the applications and production code, but had to rely on a few platform-specific files. As well as making it easier to compile and maintain, it also made it easier to port to new platforms. A new file hardware vendor or OS flavour? Simply add the settings to the include files and add new directives accordingly.

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