Проблема с конфликтующей библиотекой VC ++

StackOverflow https://stackoverflow.com/questions/2034955

  •  19-09-2019
  •  | 
  •  

Вопрос

Я работаю над проектом на C ++, который использует Qt (gui lib), VTK (graphics lib) и другую библиотеку, которая настолько малоизвестна, что я не буду упоминать ее название и вместо этого назову ее LIB_X.Проект использует Qt для компонентов графического интерфейса и VTK (точнее, расширение QVTKWidget, предоставляемое VTK и поддерживающее Qt) для визуализации геометрии..и он использует 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 of doubles), и внезапно я получал ошибку кучи в одном из методов моей статической библиотеки.Если бы я закомментировал новый элемент данных, метод статической библиотеки работал бы нормально.Мне неприятно выдавать текущую ошибку, потому что, честно говоря, я не уверен, стоит ли ее проверять, но в любом случае это здесь, на случай, если это может помочь:

примечание:он завершает работу в xutility примерно в строке 151, появляется утверждение:"файл:строка dbgheap.c:1279 выражение:_CrtIsValidHeapPointer(пользовательские данные)"

Ошибка возникает после добавления векторного вектора double к векторному вектору vector double, сбой в строке 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?

Это было полезно?

Решение

Я столкнулся с кучей LNK4006 ошибки при привязке моего приложения к библиотеке (назовем ее library LIB_Y), в которой интенсивно использовались std::vector<std::string>, что я также сделал в своем приложении.После небольшого эксперимента я нашел одно решение, которое сработало - обернуть LIB_Y в отдельную 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<double>).Ссылайтесь на заголовочные файлы LIB_X только из исходных файлов LIB_X_WRAPPER.
  3. Измените объявление всех классов и функций в вашей статической библиотеке, чтобы убедиться, что они экспортируются из библиотеки DLL (см. этот ответ если вам нужны подробности об экспорте из библиотеки DLL).

Это решение сработало для меня, потому что оно сохранило создание экземпляра (функций, сгенерированных компилятором) std::vector<std::string> класс, используемый LIBY, полностью отделен от создания экземпляра std::vector<std::string> в моем приложении.

В качестве отступления, я подозреваю, что причина сбоя, который вы видите (вы комментируете, что это в деструкторе std::vector<double>) заключается в том , что создание экземпляра std::vector<double> в вашем приложении это отличается от того, что в LIB_X.

Другие советы

Комментирование, вероятно, является просто случайной удачей - если вы повреждаете кучу, вы не всегда видите это сразу, но вектор stl будет распределять и освобождать объекты влево и вправо, поэтому неудивительно, что он находит ошибку.

Некоторые библиотеки требуют, чтобы вы включали элементы в определенном порядке.Я не уверен, почему именно, потому что для меня это все равно что сдаться и сказать, что вы не можете правильно спроектировать библиотеку, но это печальный факт.Однако до тех пор, пока вы не включаете этот lib_x везде, где вы включаете vtk, все должно быть в порядке.

Однако они могут бороться за какой-то ресурс или использовать что-то ненадлежащим образом, что делает невозможной их совместную работу.Если вы можете заставить компиляцию работать нормально, разделив их, и она по-прежнему завершается неудачей, то да, вам просто не повезло, потому что это просто ошибка в том, как был разработан этот lib_x, и поскольку он настолько неясен, вряд ли он был тщательно отлажен для всех применений.Когда что-то широко не используется, обычно это оказывается чем-то, что работает на компьютере разработчика и в проекте, но не обязательно на чьем-либо еще.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top