我的可执行文件调用了许多我自己编写的 DLL。根据这些 DLL 使用的第 3 方 C++ 库,我无法自由选择所有 DLL 的编译器设置。因此在一些DLL中_ITERATOR_DEBUG_LEVEL
设置为 2(调试版本中的默认值),但在我的可执行文件中_ITERATOR_DEBUG_LEVEL
根据严重的性能问题,设置为0。
当我现在通过一个std::string
当 DLL 尝试将其复制到本地 std::string obj 时,应用程序就会崩溃,因为 DLL 中字符串对象的内存布局与我的可执行文件中的不同。到目前为止,我通过传递 C 字符串来解决这个问题。我什至写了一个小类来转换std::map<std::string, int>
与 C-Data 中的临时表示形式之间的通信,以便在 DLL 之间传递此类数据。这有效。
我怎样才能克服这个问题?我想传递更多不同的类和容器,由于多种原因我不想使用_ITERATOR_DEBUG_LEVEL
= 2.
问题在于 std::string 和其他容器是模板类。它们是在每个二进制文件的编译时生成的,因此在您的情况下,它们的生成方式有所不同。你可以说它们不是同一个对象。
要解决此问题,您有多种解决方案,但它们都遵循相同的经验法则:不要在二进制文件之间共享的标头代码中公开任何模板代码.
您可以仅出于此目的创建特定接口,或者只是确保标头不公开模板类型和函数。您可以在二进制文件中使用这些模板类型,但不要将它们暴露给其他二进制文件。
接口中的 std::string 可以用 const char * 替换。您仍然可以在系统中使用 std::string,只需在接口中请求 const char * 并使用 std::string::c_str() 来公开您的数据。
对于地图和其他容器,您必须提供允许外部代码操作内部地图的函数。就像“Find(const char* key);”。
主要问题在于公开类的模板成员。解决此问题的一种方法是使用 PImpl 习惯用法:创建(或生成)一个 API、标头,这些标头仅公开您的二进制文件可以执行的操作,然后确保该 API 具有指向二进制文件内的真实对象的指针。该 API 将在外部使用,但在您的库内部您可以使用任何您想要的代码。 DirectX API 和其他操作系统 API 都是通过这种方式完成的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)