我如何将C ++对象传递给具有不同_ITERATOR_DEBUG_LEVEL的DLL [英] How can i pass C++ Objects to DLLs with different _ITERATOR_DEBUG_LEVEL

查看:157
本文介绍了我如何将C ++对象传递给具有不同_ITERATOR_DEBUG_LEVEL的DLL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的可执行文件调用了许多DLL,我自己写了。根据这些DLL使用的第三方C ++ libs我不能自由选择所有DLL的编译器设置。因此,在一些DLL中, _ITERATOR_DEBUG_LEVEL 设置为2(在调试版本中为默认值),但在我的可执行文件 _ITERATOR_DEBUG_LEVEL

My executable makes calls to a number of DLLs, that i wrote myself. According to 3rd party C++ libs used by these DLLs i can not freely choose compiler settings for all DLLs. Therefore in some DLLs _ITERATOR_DEBUG_LEVEL is set to 2 (default in the debug version), but in my executable _ITERATOR_DEBUG_LEVEL is set to 0, according to serious performance problems.

当我现在通过 std :: string 到DLL时,应用程序崩溃,一旦DLL试图将其复制到本地std :: string obj,因为DLL中的字符串对象的内存布局不同于我的可执行文件。到目前为止,我通过传递C字符串解决这个问题。我甚至写了一个小类,它转换 std :: map< std :: string,int> 到C-Data中的临时表示,以传递sich数据从和到DLL。这个工作。

When i now pass a std::string to the DLL, the application crashes, as soon as the DLL tries to copy it to a local std::string obj, as the memory layout of the string object in the DLL is different from that in my executable. So far i work around this by passing C-strings. I even wrote a small class that converts a std::map<std::string, int> to and from a temporary representation in C-Data in order to pass sich data from and to the DLL. This works.

我如何克服这个问题?我想传递更多不同的类和容器,并且由于几个原因我不想使用 _ITERATOR_DEBUG_LEVEL = 2.

How can i overcome this problem? I want to pass more different classes and containers, and for several reasons i do not want to work with _ITERATOR_DEBUG_LEVEL = 2.

推荐答案

问题是std :: string和其他容器是模板类。它们是在编译时为每个二进制生成的,因此在您的情况下,它们的生成方式不同。您可以说它不是相同的对象。

The problem is that std::string and other containers are template classes. They are generated at compilation time for each binary, so in your case they are generated differently. You can say it's not the same objects.

要解决这个问题,您有几个解决方案,但他们都遵循相同的经验法则: do not公开在二进制文件之间共享的头文件代码中的任何模板代码。

To fix this, you have several solutions, but they are all following the same rule of thumb : don't expose any template code in your header code shared between binaries.

您可以仅为此目的创建特定接口,公开模板类型和函数。您可以在二进制文件中使用这些模板类型,但不要将它们暴露给其他二进制文件。

You could create specific interfaces only for this purpose, or just make sure your headers don't expose template types and functions. You can use those template types inside your binaries, but just don't expose them to other binaries.

接口中的std :: string可以替换为const char *。你仍然可以在系统中使用std :: string,只需在接口中请求const char *,并使用std :: string :: c_str()来公开你的数据。

std::string in interfaces can be replaced by const char * . You can still use std::string in your systems, just ask for const char * in interfaces and use std::string::c_str() to expose your data.

对于地图和其他容器,你必须提供允许外部代码操作内部映射的函数。喜欢Find(const char * key);。

For maps and other containers you'll have to provide functions that allow external code to manipulate the internal map. Like "Find( const char* key ); ".

主要的问题是暴露类的模板成员。解决这个问题的一种方法是使用PImpl idiom:create(或generate)一个API,头文件,只是公开可以用二进制文件做什么,然后确保API有指向二进制文件中真实对象的指针。该API将在外部使用,但在您的库内,您可以用任何你想要的代码。 DirectX API和其他操作系统API都是这样做的。

The main problem will be with template members of your exposed classes. A way to fix this is to use the PImpl idiom : create (or generate) an API, headers, that just expose what can be done with your binaries, and then make sure that API have pointers to the real objects inside your binaries. The API will be used outside but inside your library you can code with whatever you want. DirectX API and other OS API are done that way.

这篇关于我如何将C ++对象传递给具有不同_ITERATOR_DEBUG_LEVEL的DLL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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