如何在我的dll界面或ABI中使用标准库(STL)类? [英] How can I use Standard Library (STL) classes in my dll interface or ABI?

查看:159
本文介绍了如何在我的dll界面或ABI中使用标准库(STL)类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在导出与视觉工作室警告C4251相关的stl类的课程时,有几个问题:例如这个问题或这个问题。
我已经在UnknownRoad上阅读了很好的解释。

There have been a few questions before on exporting a class which contains stl classes in relation to visual studio warning C4251: E.g. this question or this question. I have already read the excellent explanation at UnknownRoad.

盲目禁用警告似乎有点危险,尽管这可能是一个选择。包装所有这些std类和导出它们也不是一个选项。毕竟这是标准的模板库,也就是我想提供一个这些标准类的界面。

Blindly disabling the warning seems a little dangerous, though it may be an option. Wrapping all those std classes and exporting those is also not really an option. It is after all called the Standard Template Library... I.e., one wants to provide an interface with these standard classes.

在我的dll界面中使用stl类?什么是常见做法?

How can I use stl-classes in my dll-interface? What are common practices?

推荐答案

在进一步阅读之前,请记住一点:我的答案是从编写可用于由在不同编译器下编译的模块组成的应用程序中的可移植代码。这可以包括不同的版本,甚至不同的补丁级别的同一个编译器。

Keep in mind one thing before you read further: My answer is coming from the point of view of writing portable code that can be used in applications made up of modules compiled under different compilers. This can include different versions or even different patch levels of the same compiler.


如何在我的
中使用stl类dll-interface?

How can I use stl-classes in my dll-interface?

答案你经常不能 1

原因: STL是一个代码库,而不是像DLL这样的二进制库。它没有一个ABI,保证是一样的,无论你可以使用它。实际上,STL确实代表标准模板库,但除标准之外的其他主要操作字是模板

Reason: The STL is a code library, not a binary library like a DLL. It does not have a single ABI that is guaranteed to be the same wherever you might use it. Indeed, STL does stand for "Standard Template Library," but a key operative word here besides Standard is Template.

标准定义了每个STL类提供的方法和数据成员,并定义了这些方法要做什么;但没有更多。特别地,标准没有指定编译器编写者如何实现标准定义的功能。编译器编写者可以自由地提供一个STL类的实现,它添加标准中列出的成员函数和成员变量,只要在标准中定义 的成员仍然在那里,做标准说的。

The Standard defines the methods and data members each STL class is required to provide, and it defines what those methods are to do; but no more. In particular, the Standard doesn't specify how compiler writers should implement the Standard-defined functionality. Compiler writers are free to provide a implementation of an STL class that adds member functions and member variables not listed in the Standard, so long as those members which are defined in the Standard are still there and do what the Standard says.

也许是一个例子。标准中定义的 basic_string 类具有某些成员函数&变量。标准中的实际定义几乎是4页,但这里只是一个代码片段:

Maybe an example is in order. The basic_string class is defined in the Standard as having certain member functions & variables. The actual definition is almost 4 pages in the Standard, but here's just a snippet of it:

namespace std {
  template<class charT, class traits = char_traits<charT>,
    class Allocator = allocator<charT> >
  class basic_string {
[snip]
  public:
    // 21.3.3 capacity:
    size_type size() const;
    size_type length() const;
    size_type max_size() const;
    void resize(size_type n, charT c);
    void resize(size_type n);
    size_type capacity() const;
    void reserve(size_type res_arg = 0);
    void clear();
    bool empty() const;
[snip]
};

考虑 size() length()成员函数。标准中没有指定用于保存此信息的成员变量。实际上,根本没有定义成员变量,甚至没有保存字符串本身。那么这是如何实现的?

Consider the size() and length() member functions. There is nothing in the Standard that specified member variables for holding this information. Indeed, there are no member variables defined at all, not even to hold the string itself. So how is this implemented?

答案是多种不同的方式。一些编译器可能使用一个 size_t 成员变量来容纳大小,一个 char * 来保存字符串。另一个可能使用指向其他数据存储器的指针,该数据存储器保存该数据(在引用计数的实现中可能是这种情况)。事实上,相同编译器的不同版本甚至是补丁级别可能会改变这些实现细节。你不能依靠他们。因此,MSVC 10的实现可能如下所示:

The answer is, many different ways. Some compilers might use a size_t member variable to hold the size and a char* to hold the string. Another one might use a pointer to some other data store which holds that data (this might be the case in a reference-counted implementation). In fact, different versions or even patch levels of the same compiler may change these implementation details. You can't rely on them. So, MSVC 10's implementation might look like this:

namespace std {
  template<class charT, class traits = char_traits<charT>,
    class Allocator = allocator<charT> >
  class basic_string {
[snip]
char* m_pTheString;
};

size_t basic_string::size() const { return strlen(m_pTheString;) }

...而MSVC 10与SP1可能如下所示:

...Whereas MSVC 10 with SP1 might look like this:

namespace std {
  template<class charT, class traits = char_traits<charT>,
    class Allocator = allocator<charT> >
  class basic_string {
[snip]
vector<char> m_TheString;
};

size_t basic_string::size() const { return m_TheString.size(); }

我不是说他们这样做/ m说他们可能。这里的一点是实际的实现是平台依赖的,你真的没有办法知道什么会在其他地方。

I'm not saying they do look like this, I'm saying they might. The point here is the actual implementation is platform-dependent, and you really have no way of knowing what it will be anywhere else.

现在说你使用MSVC10写一个导出此类的DLL:

Now say you use MSVC10 to write a DLL that exports this class:

class MyGizmo
{
public:
  std::string name_;
};

什么是 sizeof(MyGizmo)

假设我上面提出的实现,在MSVC10下,它将是 sizeof(char *),但在SP1下 sizeof(vector< char>)。如果您在使用DLL的VC10 SP1中编写应用程序,则该对象的大小将看起来与实际不同。二进制接口被更改。

Assuming my proposed implementations above, under MSVC10 its going to be sizeof(char*), but under SP1 it will be sizeof(vector<char>). If you write an application in VC10 SP1 that uses the DLL, the size of the object will look different than it actually is. The binary interface is changed.

对于另一个处理方法,请参阅 C ++编码标准 (亚马逊链接)问题#63。

For another treatment of this, please see C++ Coding Standards (Amazon link) issue # 63.

1 您通常不能您实际上可以导出标准库组件或任何其他代码库组件(如Boost)当您完全控制工具链和库时,具有相当大的可靠性。

1: "You often can't" You actually can export Standard Library components or any other code library components (such as Boost) with a fair amount of reliability when you have complete control over the toolchains and the libraries.

根本的问题是,使用源代码库,事物的大小和定义可以是不同的编译器和不同版本的库之间是不同的。如果您在一个环境中工作,您可以在任何地方使用这些代码进行控制,那么您可能不会有问题。例如在一家贸易公司,所有的系统都是内部编写的,只能在内部使用,可能会这样做。

The fundamental problem is that with source code libraries the sizes and definitions of things can be different between different compilers and different versions of the library. If you are working in an environment where you control both of these things everywhere your code is used, then you probably won't have a problem. For example at a trading firm where all the systems are written in-house and used only in-house, it might be possible to do this.

这篇关于如何在我的dll界面或ABI中使用标准库(STL)类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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