2015-10-16 5 views
0

У меня есть динамическая библиотека, которая построена как в Linux, так и в Windows. При запуске моих модульных тестов против статических библиотек в обеих системах у меня нет проблем. При запуске моих модульных тестов против моей общей библиотеки в Linux все работает отлично. Моя проблема возникает при запуске моих модульных тестов с общей библиотекой в ​​Windows.Передача std :: vector по ссылке на Exported Member Function с использованием MSVC 2013 и 2015, с использованием CMake и ExternalProject_Add

Короче мой стек трассировки следующие:

UnitTest.exe!_free_dbg_nolock(void * pUserData, int nBlockUse) Line 1424 C++ 
UnitTest.exe!_free_dbg(void * pUserData, int nBlockUse) Line 1265 C++ 
UnitTest.exe!operator delete(void * pUserData) Line 54 C++ 
UnitTest.exe!std::allocator<QuadKey::QuadKey>::deallocate(QuadKey::QuadKey * _Ptr, unsigned __int64 __formal) Line 574 C++ 
UnitTest.exe!std::_Wrap_alloc<std::allocator<QuadKey::QuadKey> >::deallocate(QuadKey::QuadKey * _Ptr, unsigned __int64 _Count) Line 859 C++ 
UnitTest.exe!std::vector<QuadKey::QuadKey,std::allocator<QuadKey::QuadKey> >::_Tidy() Line 1629 C++ 
UnitTest.exe!std::vector<QuadKey::QuadKey,std::allocator<QuadKey::QuadKey> >::~vector<QuadKey::QuadKey,std::allocator<QuadKey::QuadKey> >() Line 946 C++ 
UnitTest.exe!QuadKey::BINGSYSTEM_GetChildren_Test::TestBody() Line 195 C++ 

Экспортируемые функции-члены, которые называются в теле QuadKey::BINGSYSTEM_GetChildren_Test::TestBody() взять ссылку на массив, передать его неэкспортированной функции в Anthor классе и вернуться. Например, ниже.

void QuadKey::getChildren(std::vector<QuadKey> &outKeys) const 
{ 
    m_Impl->getChildren(outKeys, (*this)); 
} 

-

// m_Impl getChildren System class is not exported. 
void System::getChildren(std::vector<QuadKey> &outKeys, 
    const QuadKey &self) const 
{ 
    for (std::uint8_t quadrant = 0; quadrant < 4; ++quadrant) { 
     QuadKey child = 
      getChild(static_cast<QuadKey::Quadrant>(quadrant), self); 
     Detail::insertVectorIfValidAndUnique(outKeys, child); 
    } 
} 

Безопасно предположить, что эта практика не является стандартом при использовании MSVC? Это передается в std::vector в экспортируемое функционирование? Если нет, то что я должен здесь принимать? Утверждение происходит, когда вектор переходит в свободную сторону, поскольку он выходит за пределы области действия от единичного тестового тела. Я попытался прояснить вектор, но такая же авария происходит даже на пустой std::vector.


AMMENDMENT:

После изменения моего UnitTest и динамическая библиотека использовать MD (MDD для отладки) вместо MT (МПД для отладки) я получаю сообщение об ошибке:

Error LNK2038 mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in main.obj UnitTest C:\Users\mehoggan\Devel\QuadKeys\build\UnitTest\libcpmtd.lib(StlCompareStringA.obj) 1 

Это связано с тем, что gtest по умолчанию скомпилирован со статическим связыванием со стандартным временем выполнения. Скажем, я не хотел изменять gtest, что было бы хорошей практикой на C++ при написании интерфейсов, которым нужны стандартные контейнеры, проходящие через границы dll?

+0

Вы связываетесь со статическим ЭЛТ или версией DLL? Существуют проблемы при статической привязке к ЭЛТ как в DLL, так и в EXE. – 1201ProgramAlarm

+0

Я не уверен на 100%. CMake генерирует мои файлы vcxproj. Где я могу найти эту информацию для вас? Лучше спросить, какую страницу в свойствах конфигурации проектов я должен проверить, чтобы проверить это? –

+0

Вы строите DLL и ее пользователя с тем же компилятором и CRT? Если вы не можете гарантировать это, то _hard_ использовать 'vector' в интерфейсе DLL [здесь] (http://www.unknownroad.com/rtfm/VisualStudio/warningC4251.html) является приятным (хотя и старым) тема – Rostislav

ответ

1

Это потому, что вы статически связываетесь с C Runtime. Вам нужно связать с версией DLL. Построить с /MD, а не /MT.

См. Potential errors passing CRT Objects Across DLL Boundaries о проблемах, которые могут возникнуть.

+0

Я сделал CMake для установки библиотеки времени выполнения для использования динамической компоновки. Однако при этом он создал другой набор ошибок, так как настроен gtest. Я обновил свой пост, чтобы отразить более понятную проблему. –