从dll返回std :: string / std :: list [英] returning std::string/std::list from dll

查看:171
本文介绍了从dll返回std :: string / std :: list的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

简短的问题。

我刚刚得到了一个我应该与之交互的dll。
Dll使用crt从msvcr90D.dll(通知D),并返回std :: strings,std :: lists和boost :: shared_ptr。

I just got a dll I'm supposed to interface with. Dll uses crt from msvcr90D.dll (notice D), and returns std::strings, std::lists, and boost::shared_ptr. Operator new/delete is not overloaded anywhere.

我假设crt mixup(msvcr90.dll在发行版本,或者如果其中一个组件用新的crt重建等等)最终会导致问题,并且dll应该被重写,以避免返回任何可能调用new / delete(即任何可以调用delete在我的代码中的内存块被分配(可能有不同的crt)在dll)。

I assume crt mixup (msvcr90.dll in release build, or if one of components is rebuilt with newer crt, etc) is bound to cause problems eventually, and dll should be rewritten to avoid returning anything that could possibly call new/delete (i.e. anything that could call delete in my code on a block of memory that was allocated (possibly with different crt) in dll).

我对不对?

推荐答案

请记住,dll包含代码,而不是内存。分配的内存属于进程(1)。当您在进程中实例化对象时,将调用构造函数代码。在该对象的生命周期中,您将调用其他代码(方法)来处理该对象的内存。然后当对象离开时,调用析构函数代码。

The main thing to keep in mind is that dlls contain code and not memory. Memory allocated belongs to the process(1). When you instantiate an object in your process, you invoke the constructor code. During that object's lifetime you will invoke other pieces of code(methods) to work on that object's memory. Then when the object is going away the destructor code is invoked.

STL模板不是从dll中显式导出的。代码静态链接到每个dll。因此,当std :: string s在a.dll中创建并传递给b.dll时,每个dll将有两个不同的string :: copy方法。在a.dll中调用的复制调用a.dll的复制方法...如果我们在b.dll和调用复制中使用s,b.dll中的复制方法将被调用。

STL Templates are not explicitly exported from the dll. The code is statically linked into each dll. So when std::string s is created in a.dll and passed to b.dll, each dll will have two different instances of the string::copy method. copy called in a.dll invokes a.dll's copy method... If we are working with s in b.dll and call copy, the copy method in b.dll will be invoked.

这是为什么在西蒙的回答中他说:

This is why in Simon's answer he says:


坏事情会发生,除非你可以
总是保证您的整个
二进制文件都是用相同的
工具链构建的。

Bad things will happen unless you can always guarantee that your entire set of binaries is all built with the same toolchain.

因为如果由于某种原因,字符串的副本不同a.dll和b.dll之间,奇怪的事情会发生。更糟的是,如果字符串本身是不同的a.dll和b.dll,和析构函数在一个知道清除额外的内存,其他人忽略...你可能很难跟踪内存泄漏。也许更糟的是,a.dll可能是建立在一个完全不同的版本的STL(即STLPort),而b.dll是使用微软的STL实现构建。

because if for some reason, string s's copy differs between a.dll and b.dll, weird things will happen. Even worse if string itself is different between a.dll and b.dll, and the destructor in one knows to clean extra memory that the other ignores... you can have difficult to track down memory leaks. Maybe even worse... a.dll might have been built against a completely different version of the STL (ie STLPort) while b.dll is built using Microsoft's STL implementation.

那么你该怎么办?在我们工作的地方,我们对每个dll的工具链和构建设置都有严格的控制。所以当我们开发内部dll,我们自由地传递STL模板。我们仍然有一些问题,在很少的情况下出现,因为有人没有正确地设置他们的项目。然而,我们发现STL的便利性值得偶尔出现的问题。

So what should you do? Where we work, we have strict control over the toolchain and build settings for each dll. So when we develop internal dll's, we freely transfer STL templates around. We still have problems that on rare occasion crop up because someone didn't correctly setup their project. However we find the convenience of the STL worth the occasional problem that crops up.

为了将dll暴露给第三方,这完全是另一个故事。除非您要严格要求客户端的特定构建设置,否则您希望避免导出STL模板。我不建议您严格执行客户的特定制作设置...他们可能有另一个第三方工具,希望您使用完全相反的构建设置。

For exposing dlls to 3rd parties, that's another story entirely. Unless you want to strictly require specific build settings from clients, you'll want to avoid exporting STL templates. I don't recommend strictly enforcing your clients to have specific build settings... they may have another 3rd party tool that expects you to use completely opposite build settings.

1)是的,我知道静态和本地实例化/删除dll加载/卸载。

(1) Yes I know static and locals are instantiated/deleted on dll load/unload.

这篇关于从dll返回std :: string / std :: list的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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