使用MSVC 2013和2015,使用CMake和ExternalProject_Add通过引用导出的成员函数传递std :: vector

时间:2015-10-16 02:17:57

标签: c++ visual-c++ cmake dllexport

我有一个在Linux和Windows中构建的动态库。在针对两个系统下的静态库运行我的单元测试时,我没有任何问题。当我在linux中运行我的单元测试我的共享库时,一切正常。在针对Windows中的共享库运行单元测试时,我的问题就出现了。

简而言之,我的堆栈跟踪如下:

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传递给导出的函数?如果不是我应该在这里假设什么?断言发生在向量变为空闲时,因为它超出了单元测试体的范围。我试图在向量上调用clear,但即使在空std::vector上也会发生同样的崩溃。

AMMENDMENT:

将UnitTest和Dynamic库更改为使用MD(MDd for debug)而不是MT(MTd for debug)后,我收到错误:

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在编写需要跨越dll边界的标准容器的接口时,什么是好的C ++实践?

1 个答案:

答案 0 :(得分:1)

这是因为您静态链接到C运行时。您需要链接DLL版本。使用/MD构建,而不是/MT

有关这可能导致的问题,请参阅Potential errors passing CRT Objects Across DLL Boundaries