只有少数方法(静态或共享库)无法解析的外部符号

Unresolved external symbol in only a few methods (static or shared library)

这让我抓狂,使用 MSVC14.1 我正在创建一个库 A 以用于另一个共享库 B。库 A 是静态的还是共享的都没有关系,我总是以 3 个未解决的问题告终外部符号:

[build] GroomDeformer.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: static class avPoly::PolyMesh __cdecl avPoly::PolyMesh::create(class std::vector<struct glm::vec<3,float,0>,class std::allocator<struct glm::vec<3,float,0> > > const &,class std::vector<unsigned int,class std::allocator<unsigned int> > const &,class std::vector<unsigned __int64,class std::allocator<unsigned __int64> > const &)" (__imp_?create@PolyMesh@avPoly@@SA?AV12@AEBV?$vector@U?$vec@M[=10=]A@@glm@@V?$allocator@U?$vec@M[=10=]A@@glm@@@std@@@std@@AEBV?$vector@IV?$allocator@I@std@@@4@AEBV?$vector@_KV?$allocator@_K@std@@@4@@Z) referenced in function "public: void __cdecl avGroomCore::GroomDeformer::ConstructMesh(class std::vector<struct glm::vec<3,float,0>,class std::allocator<struct glm::vec<3,float,0> > > const &,class std::vector<unsigned __int64,class std::allocator<unsigned __int64> > const &,class std::vector<unsigned int,class std::allocator<unsigned int> > const &)" (?ConstructMesh@GroomDeformer@avGroomCore@@QEAAXAEBV?$vector@U?$vec@M[=10=]A@@glm@@V?$allocator@U?$vec@M[=10=]A@@glm@@@std@@@std@@AEBV?$vector@_KV?$allocator@_K@std@@@4@AEBV?$vector@IV?$allocator@I@std@@@4@@Z) [C:\Users\tufto\PycharmProjects\avgroom\build\src\core\Core.vcxproj]
[build] GroomDeformer.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: class avPoly::FaceLocation __cdecl avPoly::PolyMesh::getClosestLocation(struct glm::vec<3,float,0> const &)" (__imp_?getClosestLocation@PolyMesh@avPoly@@QEAA?AVFaceLocation@2@AEBU?$vec@M[=10=]A@@glm@@@Z) referenced in function "public: void __cdecl avGroomCore::GroomDeformer::DeformGroom(void)" (?DeformGroom@GroomDeformer@avGroomCore@@QEAAXXZ) [C:\Users\tufto\PycharmProjects\avgroom\build\src\core\Core.vcxproj]
[build] GroomDeformer.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: struct glm::vec<3,float,0> __cdecl avPoly::PolyMesh::getAttributeValueFromLocation(class avPoly::FaceLocation const &,class avPoly::Attribute<struct glm::vec<3,float,0> > &)" (__imp_?getAttributeValueFromLocation@PolyMesh@avPoly@@QEAA?AU?$vec@M[=10=]A@@glm@@AEBVFaceLocation@2@AEAV?$Attribute@U?$vec@M[=10=]A@@glm@@@2@@Z) referenced in function "public: void __cdecl avGroomCore::GroomDeformer::DeformGroom(void)" (?DeformGroom@GroomDeformer@avGroomCore@@QEAAXXZ) [C:\Users\tufto\PycharmProjects\avgroom\build\src\core\Core.vcxproj]

现阶段我不知道该做什么。我查看了 dumpbin 中的符号,我确实得到了签名,例如:

__imp_?create@PolyMesh@avPoly@@SA?AV12@AEBV?$vector@U?$tvec3@M[=11=]A@@glm@@V?$allocator@U?$tvec3@M[=11=]A@@glm@@@std@@@std@@AEBV?$vector@IV?$allocator@I@std@@@4@AEBV?$vector@_KV?$allocator@_K@std@@@4@@Z

我唯一能注意到的是错误签名中有 "tvec3" 而不是 "vec"。我认为这是指我必须为库 A 进行 GLM 的类型定义,例如:

typedef glm::vec3 Vector3;
typedef std::vector<Vector3> Vector3Array;

关于如何调试它的任何想法或指南?我已经尝试了所有我能想到的,但不能把我的手指放在上面。最糟糕的是,在库 A 项目中,我有另一个迷你可执行文件来测试它链接得很好......(全部使用 CMake)。两个 CMake 配置相同。

以下是头文件中的方法签名:

AVPOLYLIB_API
static PolyMesh create(Vector3Array const &positions, UIntArray const &faceVertexCounts, IndexArray const &faceVertexIndices);

AVPOLYLIB_API
FaceLocation getClosestLocation(Vector3 const &point);

AVPOLYLIB_API
Vector3 getAttributeValueFromLocation(FaceLocation const & location, Attribute<Vector3> &attribute);

DLL导出完成如下:

#ifdef AVPOLYLIB_STATIC
    #define AVPOLYLIB_API
#else
    #ifdef AVPOLYLIB_EXPORTS  
        #define AVPOLYLIB_API __declspec(dllexport)   
    #else  
        #define AVPOLYLIB_API __declspec(dllimport)   
    #endif 
#endif

这些方法中使用的类型声明如下(在库命名空间内):

class FaceLocation {
        public:
            Index triangleId;
            Vector3 barycentricCoordinates;
};

typedef std::vector<Vector3> Vector3Array;
typedef std::vector<Index> IndexArray;
typedef std::vector<unsigned int> UIntArray;

解决了!这很愚蠢:glm headers 存在问题,因为它们在两个库中都有子模块,但由于某种原因版本不匹配。所以我在导出的符号中确实有错误的签名。使用同一文件夹中的 headers 解决了问题。