- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
在导出包含与 Visual Studio 警告 C4251 相关的 STL 类的类之前,有几个问题:例如这个问题或这个问题。我已经阅读了 UnknownRoad 上的精彩解释。
盲目地禁用警告似乎有点危险,尽管它可能是一种选择。包装所有这些 std 类并导出它们也不是一个真正的选择。毕竟它被称为标准模板库...即,想要为这些标准类提供一个接口(interface)。
如何在我的 dll 接口(interface)中使用 STL 类?有哪些常见做法?
最佳答案
在进一步阅读之前请记住一件事:我的回答来自编写可移植代码的角度,这些代码可用于由在不同编译器下编译的模块组成的应用程序中。这可能包括同一编译器的不同版本甚至不同的补丁级别。
How can I use stl-classes in my dll-interface?
回答:你通常不能1。
原因: STL 是一个代码库,而不是像 DLL 这样的二进制库。它没有一个单一的 ABI 可以保证在您使用它的任何地方都是相同的。事实上,STL 确实代表“Standard Template Library”,但除了 Standard 之外,这里的一个关键操作词是 Template。
标准定义了每个 STL 类必须提供的方法和数据成员,并定义了这些方法的用途;但没有了。特别是,标准没有指定编译器编写者应该如何实现标准定义的功能。编译器编写者可以自由地提供一个 STL 类的实现,它添加了标准中未列出的成员函数和成员变量,只要这些成员在标准中定义仍然在那里,按照标准所说的去做。
也许可以举个例子。 basic_string
类在标准中被定义为具有某些成员函数和变量。标准中的实际定义差不多有 4 页,但这里只是其中的一个片段:
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()
成员函数。标准中没有任何内容指定用于保存此信息的成员变量。实际上,根本没有定义任何成员变量,甚至没有定义字符串本身。那么这是如何实现的呢?
答案是,有很多不同的方式。一些编译器可能使用 size_t
成员变量来保存大小和 char*
握住字符串。另一个可能使用指向保存该数据的其他数据存储的指针(这可能是引用计数实现中的情况)。事实上,同一编译器的不同版本甚至补丁级别都可能改变这些实现细节。你不能依赖他们。因此,MSVC 10 的实现可能如下所示:
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;) }
...而带有 SP1 的 MSVC 10 可能如下所示:
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(); }
我不是说他们确实看起来像这样,我是说他们可能。这里的重点是实际的实现是依赖于平台的,你真的无法知道它在其他任何地方会是什么。
现在假设您使用 MSVC10 编写一个导出此类的 DLL:
class MyGizmo
{
public:
std::string name_;
};
什么是sizeof(MyGizmo)
?
假设我在上面提出的实现,在 MSVC10 下它将是 sizeof(char*)
, 但在 SP1 下它将是 sizeof(vector<char>)
.如果您在 VC10 SP1 中编写使用 DLL 的应用程序,则对象的大小看起来与实际不同。二进制接口(interface)改变了。
有关此问题的另一种处理方法,请参阅 C++ 编码标准 (Amazon link ) 第 63 期。
1: "你经常做不到"你实际上可以相当可靠地导出标准库组件或任何其他代码库组件(例如 Boost)当您完全控制工具链和库时。
根本问题在于,对于源代码库,不同编译器和库的不同版本之间事物的大小和定义可能不同。如果您在使用代码的任何地方都可以控制这两个东西的环境中工作,那么您可能不会遇到问题。例如,在所有系统都在内部编写并仅在内部使用的贸易公司中,这样做是可能的。
关于c++ - 如何在我的 dll 接口(interface)或 ABI 中使用标准库 (STL) 类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5661738/
我正在尝试在我的代码库中为我正在编写的游戏服务器更多地使用接口(interface),并了解高级概念以及何时应该使用接口(interface)(我认为)。在我的例子中,我使用它们将我的包相互分离,并使
我有一个名为 Widget 的接口(interface),它在我的整个项目中都在使用。但是,它也用作名为 Widget 的组件的 Prop 。 处理此问题的最佳方法是什么?我应该更改我的 Widget
有一个接口(interface)可以是多个接口(interface)之一 interface a {x:string} interface b {y:string} interface c {z:st
我遇到了一种情况,我需要调用第三方服务来获取一些信息。这些服务对于不同的客户可能会有所不同。我的界面中有一个身份验证功能,如下所示。 interface IServiceProvider { bool
在我的例子中,“RequestHandlerProxy”是一个结构,其字段为接口(interface)“IAdapter”,接口(interface)有可能被调用的方法,该方法的输入为结构“Reque
我有一个接口(interface)Interface1,它已由类A实现,并且设置了一些私有(private)变量值,并且我将类A的对象发送到下一个接受输入作为Interface2的类。那么我怎样才能将
假设我有这样的类和接口(interface)结构: interface IService {} interface IEmailService : IService { Task SendAs
有人知道我在哪里可以找到 XML-RPC 接口(interface)的定义(在 OpenERP 7 中)?我想知道创建或获取对象需要哪些参数和对象属性。每个元素的 XML 示例也将非常有帮助。 最佳答
最近,我一直在阅读有关接口(interface)是抽象的错误概念的文章。一篇这样的帖子是http://blog.ploeh.dk/2010/12/02/InterfacesAreNotAbstract
如果我有一个由第三方实现的现有 IInterface 后代,并且我想添加辅助例程,Delphi 是否提供了任何简单的方法来实现此目的,而无需手动重定向每个接口(interface)方法?也就是说,给定
我正在尝试将 Article 数组分配给我的 Mongoose 文档,但 Typescript 似乎不喜欢这样,我不知道为什么它显示此警告/错误,表明它不可分配. 我的 Mongoose 模式和接口(
我有两个接口(interface): public interface IController { void doSomething(IEntity thing); } public inte
是否可以创建一个扩展 Serializable 接口(interface)的接口(interface)? 如果是,那么扩展接口(interface)的行为是否会像 Serilizable 接口(int
我试图在两个存储之间创建一个中间层,它从存储 A 中获取数据,将其转换为相应类型的存储 B,然后存储它。由于我需要转换大约 50-100 种类型,我希望使用 map[string]func 并根据 s
我正在处理一个要求,其中我收到一个 JSON 对象,其中包含一个日期值作为字符串。我的任务是将 Date 对象存储在数据库中。 这种东西: {"start_date": "2019-05-29", "
我们的方法的目标是为我们现有的 DAO 和模型类引入接口(interface)。模型类由各种类型的资源 ID 标识,资源 ID 不仅仅是随机数,还带有语义和行为。因此,我们必须用对象而不是原始类型来表
Collection 接口(interface)有多个方法。 List 接口(interface)扩展了 Collection 接口(interface)。它声明与 Collection 接口(int
我有一个 Java 服务器应用程序,它使用 Jackson 使用反射 API 对 DTO 进行一般序列化。例如对于这个 DTO 接口(interface): package com.acme.libr
如果我在 Kotlin 中有一个接口(interface): interface KotlinInterface { val id: String } 我可以这样实现: class MyCla
我知道Java中所有访问修饰符之间的区别。然而,有人问了我一个非常有趣的问题,我很难找到答案:Java 中的 private 接口(interface)和 public 接口(interface)有什
我是一名优秀的程序员,十分优秀!