VC++库冲突问题

发布于 2024-08-17 11:46:05 字数 1836 浏览 4 评论 0原文

我正在开发一个 C++ 项目,该项目使用 Qt (gui lib)、VTK (graphics lib) 和另一个非常晦涩的库,我不会提及它的名称,而是将其称为 LIB_X。该项目使用 Qt 作为 gui 组件,使用 VTK(更准确地说是支持 Qt 的 VTK 提供的 QVTKWidget 扩展)来渲染几何图形。并且它使用 LIB_X 来收集和操作几何图形。

问题是,事实证明 LIB_X 实际上使用了 VTK(在哪里以及如何使用,我不知道,它是闭源的)。起初没有问题,使用链接的两个库进行编译都进展顺利,但在某些时候我调用了某个(并且非常需要)LIB_X 函数,并且编译导致了一堆关于已经定义的 VTK lib/obj 的内容在 LIB_X dll 错误中。

例如(请注意,这是与 /FORCE:MULTIPLE 一起使用的,所以这里是一个警告,如果您想要不带 /FORCE:MULTIPLE 的错误,请告诉我,我会发布它):

1>LIB_X.lib(LIB_X.dll) : warning LNK4006: "public: __thiscall std::vector<double,class std::allocator<double> >::~vector<double,class std::allocator<double> >(void)" (??1?$vector@NV?$allocator@N@std@@@std@@QAE@XZ) already defined in vtkCommon.lib(vtkInformationDoubleVectorKey.obj);

我尝试使用 /FORCE:MULTIPLE ,它似乎是起初是一个奇迹,但我在代码中遇到了随机错误,这些错误主要会导致堆错误。我决定从主项目中删除对 LIB_X 的所有引用,并创建一个静态库来处理所有 LIB_X 内容。我不是 C++ 专家,所以我不确定当您使用预编译的库时它如何处理库冲突,但在将静态库链接到我的主项目时我仍然收到库冲突错误,所以我仍然必须使用/FORCE:MULTIPLE。

一旦我有了静态库,似乎随机错误就消失了,我可以通过静态库在主项目中使用 LIB_X 方法做很多事情,但是突然间,我在我的主项目中添加了一个新的数据成员类(双精度的 std::vector),突然我在静态库的方法之一中遇到堆错误。如果我注释掉新的数据成员,静态库的方法将运行良好。我不想给出当前的错误,因为老实说,我不确定检查它是否值得,但无论如何,它是为了以防万一它可以提供帮助:

注意:它在大约第 151 行崩溃到 xutility,弹出断言: “文件:dbgheap.c行:1279表达式:_CrtIsValidHeapPointer(pUserData)”

将向量向量双精度型添加到向量向量向量双精度型后出现错误,在push_back行上崩溃:

std::vector<std::vector<double>> tmpVec;
for(srvl_iter = srvl.begin(); srvl_iter != srvl.end(); ++srvl_iter)
{
 tmpVec.push_back((*srvl_iter).getControlPoints());
}
this->_splines.push_back(tmpVec); //CRASH

当我添加新的数据成员时,它才开始崩溃。到我的主项目(与静态库分开!)注释掉新的数据成员可以消除错误。

std::vector<std::vector<std::vector<double>>> _geometry; 

所以, /FORCE:MULTIPLE 看起来很糟糕,我收到了一些对我来说没有意义的随机错误。还有其他解决方案吗?我完蛋了吗?我可以使用 LIB_X 的 VTK 链接做些什么吗?

I am working on a C++ project that uses Qt (gui lib), VTK (graphics lib) and another library which is so obscure I won't mention its name and will instead call it LIB_X. The project uses Qt for the gui components and VTK (more precisely the QVTKWidget extension provided by VTK that supports Qt) for rendering geometry.. and it uses LIB_X to gather and manipulate geometry.

The problem is that it turns out that LIB_X actually uses VTK (where and how, I don't know, it's closed source). At first there was no problem, compiling with both libs linked was going fine, but at some point I called a certain (and highly needed) LIB_X function and compiling led to a bunch of 'blah blah something about a VTK lib/obj already defined in LIB_X dll' errors.

e.g. (and note this is with /FORCE:MULTIPLE so it's a warning here, let me know if you want the error without /FORCE:MULTIPLE and I'll post it):

1>LIB_X.lib(LIB_X.dll) : warning LNK4006: "public: __thiscall std::vector<double,class std::allocator<double> >::~vector<double,class std::allocator<double> >(void)" (??1?$vector@NV?$allocator@N@std@@@std@@QAE@XZ) already defined in vtkCommon.lib(vtkInformationDoubleVectorKey.obj);

I tried using /FORCE:MULTIPLE and it seemed to be a miracle at first, but I am getting random errors in code that would mostly give heap errors. I decided to remove all references to LIB_X from the main project and created a static lib that would handle all LIB_X stuff. I'm not a C++ expert, so I'm not certain how it handles lib clashing when you're using a pre-compiled lib, but I still received lib clashing errors when linking my static lib into my main project, so I still have to use /FORCE:MULTIPLE.

Once I had the static lib it seemed like the random errors had gone away, I was able to do a lot with LIB_X methods in the main project via the static lib, BUT out of nowhere, I added a new data member to my main project's class (a std::vector of doubles) and suddenly I was getting a heap error in one of my static library's methods. If I commented out the new data member, the static library's method would run fine. I hate to give the current error, because honestly I'm not sure if examining it will be worthwhile, but here it is anyway in case it can help:

note: it crashes to xutility on about line 151, pops up assertion:
"file: dbgheap.c line: 1279 expression: _CrtIsValidHeapPointer(pUserData)"

The error comes after adding a vector vector double to a vector vector vector double, crashing on the push_back line:

std::vector<std::vector<double>> tmpVec;
for(srvl_iter = srvl.begin(); srvl_iter != srvl.end(); ++srvl_iter)
{
 tmpVec.push_back((*srvl_iter).getControlPoints());
}
this->_splines.push_back(tmpVec); //CRASH

It only started crashing here when I added a new data member to my main project (separate from the static lib!) Commenting out the new data member takes the error away.

std::vector<std::vector<std::vector<double>>> _geometry; 

So, /FORCE:MULTIPLE seems bad, I get random errors that just don't make sense to me. Are there other solutions? Am I screwed? Is there something I can do with LIB_X's linking of VTK?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

ゃ人海孤独症 2024-08-24 11:46:05

在将我的应用程序链接到大量使用 std::vector 的库(称为库 LIB_Y)时,我遇到了一堆 LNK4006 错误,我也在我的应用程序中做到了这一点。经过一番试验后,我发现了一个有效的解决方案——将 LIB_Y 包装在一个单独的 DLL 中,该 DLL 调用 LIB_Y(例如 LIB_Y_WRAPPER),然后将主应用程序链接到 LIB_Y_WRAPPER。

要尝试我的建议,您需要:

  1. 将“处理所有 LIB_X 内容的静态库”从静态 LIB 项目更改为 DLL 项目(我将其称为 LIB_X_WRAPPER)。
  2. 确保 LIB_X_WRAPPER 的头文件不包含任何 LIB_X 头文件。这一点非常重要,因为包装器需要将您的应用与 LIB_X 头文件中声明的数据类型(例如 std::vector)完全隔离。仅从 LIB_X_WRAPPER 的源文件中引用 LIB_X 的头文件。
  3. 更改静态库中所有类和函数的声明,以确保它们从 DLL 导出(请参阅 此答案(如果您需要有关从 DLL 导出的详细信息)。

这个解决方案对我有用,因为它使 LIBY 使用的 std::vector类的实例化(编译器生成的函数)与 std:: 的实例化完全分开。我的应用程序中的向量

顺便说一句,我怀疑您所看到的崩溃的原因(您评论它是在 std::vector的析构函数中)是因为 std::vector< 的实例化您的应用中的 ;double> 与 LIB_X 中的不同。

I encountered a bunch of LNK4006 errors when linking my app to a library (call it library LIB_Y) that made heavy use of std::vector<std::string>, which I also did in my app. After a bit of experimenting I found one solution that worked -- wrap LIB_Y in a separate DLL that calls LIB_Y (LIB_Y_WRAPPER, say), and then link the main app against LIB_Y_WRAPPER.

To try out my suggestion you will need to:

  1. Change your "static lib that handles all LIB_X stuff" from a static LIB project into a DLL project (which I will call LIB_X_WRAPPER).
  2. Make sure the header files of LIB_X_WRAPPER don't include any of the LIB_X header files. This is really important because the wrapper needs to completely isolate your app from the data types declared in the LIB_X header files (such as std::vector<double>). Only refer to LIB_X's header files from within the source files of LIB_X_WRAPPER.
  3. Change the declaration of all classes and functions in your static lib to ensure they are exported from the DLL (see this answer if you need details about exporting from a DLL).

This solution worked for me because it kept the instantiation (compiler generated functions) of the std::vector<std::string> class used by LIBY completely separate from the instantiation of std::vector<std::string> in my app.

As an aside, I suspect the cause of the crash you are seeing (you comment it is in the destructor of std::vector<double>) is because the instantiation of std::vector<double> in your app is different to that in LIB_X.

月下凄凉 2024-08-24 11:46:05

注释掉可能只是随机的运气 - 如果你破坏了堆,你并不总是能立即看到它,但 stl 向量会左右分配和释放东西,所以难怪它会发现错误。

有些库要求您按特定顺序包含内容。我不确定为什么,因为对我来说,这似乎是放弃并说你无法正确设计一个库,但这是一个可悲的事实。只要你不在包含 vtk 的任何地方包含这个 lib_x 就应该没问题。

然而,他们可能会争夺某些资源或使用不当,导致他们无法一起工作。如果您能够通过隔离它们来使编译正常工作,但它仍然失败,那么是的,您只是运气不好,因为这只是这个 lib_x 设计方式的失败,而且由于它是如此晦涩难懂,所以不太可能被针对所有用途进行了彻底调试。当某些东西没有被广泛使用时,它通常最终会在开发人员的机器和项目上运行,但不一定在其他人的机器和项目上运行。

The commenting out is probably just random luck - if you are corrupting the heap you don't always see it right away but an stl vector will allocate and deallocate things left and right so it's no wonder it's finding the error.

Some libs require you include things in a certain order. I am not sure why exactly because to me it seems like giving up and saying you can't design a library properly, but it's the sad fact. So long as you don't include this lib_x anywhere that you include vtk it should be fine, though.

However, they might be fighting over some resource or using something improperly that makes it impossible for them to work together. If you are able to get the compile to work ok by segregating them and it still fails then yes you are just out of luck because it's just a failing in the way that this lib_x was designed and since it's so obscure it's not likely to have been thoroughly debugged against all uses. When something's not widely used it usually ends up being something that works on the developer's machine and project but not necessarily anyone else's.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文