2012-02-26 128 views
4

很确定我知道这个答案(思考否),但是可以安全地接受/返回std :: function在API中的值(跨模块边界)?使用std :: function(跨越模块边界)

我想'不',因为我不认为有任何保证,一个供应商的std :: function实现与另一个兼容。是这样吗?

如果答案不是我所怀疑的,那么你们怎么处理这种事情呢?我可能不得不求助于实现我自己的或者只是一起避免诸如std :: function之类的东西(例如:使用函数指针或函数)。 :-(在许多情况下,我发现自己在这么做的时候(重新创建了很多标准的C++库,并且很遗憾甚至制作了我们自己的兼容STL的矢量类型,同时支持范围ctor和fill ctor,自定义分配器等等。当然,这并不好玩,我怀疑它和标准实现一样好),只是因为人们可能会动态链接到一个库,例如MSVC 2010使用mingw编写的二进制文件实现std :: function,例如

当然,替代方案是在我们的API中不使用这些类型的C++特性,并且使用C接口,但这对我们来说代价相当昂贵,因为我们使用我们的API作为中央API内部和第三方开发

+1

这与*任何*编译的C++库面临的问题相同...... – 2012-02-26 21:02:14

+0

@KerrekSB:不是静态库。只是试图跨DLL边界使用标准库类型的DLL。它不是用C类型保存的(比如'FILE *'),但是你通常不会看到人们想要通过DLL来抛出它们。 – 2012-02-26 21:05:12

+0

似乎是这样。我总是想知道人们如何处理它(例如:如果有一些交叉编译器的选择,我们可以使用这些替代方法,可以跨模块边界工作,比如说,通过我们的SDK分发源代码)。总是希望有更多的关注跨越模块边界使用C++,因为我们通过在DLL /共享库中实现的API来集中开发,像std :: function这样的东西在常规回调函数或函数中非常有用,尤其是在添加lambda表达式。 – stinky472 2012-02-26 21:06:21

回答

6

你可以做到这一点,只要e一个人玩的是相同的规则,而你的标准库是动态链接的。如果第三方知道他们必须使用特定的编译器,以及该编译器的特定版本以及某些特定的构建标志,那么这是没有问题的。

即使你编写自己的包装器,他们也必须使用该包装器的特定版本,尽管显然这更容易实施。

但实际上,这是您尝试通过DLL进行互操作所付出的代价:每个人都必须位于同一页面上,否则它将无法工作。或者你必须坚持使用基本类型或本土控制的界面。

+0

我明白了,谢谢。本土解决方案就是我们一直在做的事情,但复制一些基本标准库类型的用处变得非常痛苦,例如vector,wstring,unique_ptr,shared_ptr,function等等,这些都可以很好用用于构建公共接口。如果没有人已经这样做,我几乎可以开始一个开源,简约,交叉编译的解决方案。我们正在考虑提高效率,但这样做也有点棘手,因为boost非常巨大,开发人员可能希望使用比我们发布的版本更新的版本。 – stinky472 2012-02-26 21:10:06

+0

提升怎么样? – ronag 2012-02-26 21:13:12

+0

增强是我们考虑发布的内容,但它有点困难,因为它太大了,我们经常想知道如果第三方已经在使用与我们分发的版本不同的版本会发生什么。这会使我们的SDK比它大很多倍,并且使用它的某些部分有点困难,因为许多功能都是从其他部分构建的。也许我们应该再看一遍,因为在这种情况下boost :: function会很好地工作,并且支持许多不同的编译器当然是非常好的。 – stinky472 2012-02-26 21:15:23