c++ - 将内联数学库与预编译头文件结合使用时出现链接错误

标签 c++ sse inline-code

今天我遇到了一个很奇怪的问题。我有一个针对 SSE 优化的数学库,因此几乎所有功能都声明为内联。为简化起见,我将仅使用一个类 Vector3 来解释问题:

Vector3 在 Vector3.h 中声明,如下所示:

#ifndef VIRTUS_VECTOR3_H
#define VIRTUS_VECTOR3_H

#ifndef VEC3INLINE
  #if(_DEBUG)
    #define VEC3INLINE inline
  #else
    #define VEC3INLINE __forceinline
  #endif
#endif

namespace Virtus {

struct Vector3
{
  union
  {
    struct { f32 x,y,z; };
    f32 v[3];
  };

  Vector3(void);
  Vector3(const Vector3& rhs);
  Vector3(f32 xx, f32 yy, f32 zz);

  VEC3INLINE Vector3& operator=(const Vector3& rhs);

  VEC3INLINE Vector3 operator+(f32 rhs) const;
  VEC3INLINE Vector3 operator-(f32 rhs) const;
  VEC3INLINE Vector3 operator*(f32 rhs) const;
  VEC3INLINE Vector3 operator/(f32 rhs) const;
  VEC3INLINE Vector3& operator+=(f32 rhs);
  VEC3INLINE Vector3& operator-=(f32 rhs);
...

#include "vector3.inl"
#endif

在 vector3.inl 中,我继续定义所有函数

namespace Virtus {

Vector3::Vector3(void)
  : x(0.0f), y(0.0f), z(0.0f)
{
}

Vector3::Vector3(const Vector3& rhs)
  : x(rhs.x), y(rhs.y), z(rhs.z)
{
}

Vector3::Vector3(f32 xx, f32 yy, f32 zz)
  : x(xx), y(yy), z(zz)
{
    }

VEC3INLINE Vector3& Vector3::operator=(const Vector3& rhs)
{
  memcpy(v, rhs.v, sizeof(v));
  return *this;
}

    ...

然后我将我所有的数学对象包含在一个名为 math.h 的文件中

#ifndef VIRTUS_MATH_H
#define VIRTUS_MATH_H

#include "vector2.h"
#include "vector3.h"
#include "vector4.h"
#include "matrix4.h"
#include "primesearch.h"

namespace Virtus
{
  class MathException
  {
  public:
    enum ErrorCode
    {
      PRIME_SEARCH_INVALID_ELEMENTS,
      PRIME_SEARCH_UNSUFFNUM_PRIMES
    };

    MathException(ErrorCode code) : m_Error(code) {}
    ErrorCode What(void) const { return m_Error; }

  private:
    ErrorCode m_Error;
  };
} // namespace virtus

#endif // Include Guard

math.h 包含在我的预编译头文件中(precompiled.h aka stdafx.h)

我使用 Visual Studio 2008,它应该会自动从构建过程中排除 .inl 文件。

这是我收到的链接器错误:

Error 1 error LNK2005: "public: __thiscall Virtus::Vector3::Vector3(void)" (??0Vector3@Virtus@@QAE@XZ) already defined in precompiled.obj main.obj Virtus

我尝试了几乎所有可以想象的方式来解决这个问题,比如手动从构建中排除所有 inl 文件;不在预编译文件中包含 math.h,但只在我需要的地方包含它(在这种情况下,我得到一个类似的已经定义的链接器错误);从 inl 扩展名更改为 cpp 扩展名,等等。我能够修复它的唯一方法是使用 #pragma once 而不是 include guards。所以我现在最好的猜测是它与预编译头文件和包含保护的组合有关,但我不太确定如何解决这个问题。

帮助将不胜感激!

最佳答案

vector3.inl 中的每个定义都需要使用inline 显式定义。

关于c++ - 将内联数学库与预编译头文件结合使用时出现链接错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6474480/

相关文章:

c++11 - x86-SSE指令是否具有自动发布获取指令?

asp.net - 如何在 ASP.NET 页面内定义命名空间(内联代码方法)?

html - 下载完整 CSS 后是否应该删除内联 CSS?

c++ - _mm_load_ps 导致段错误

python - 使用 python scipy.weave 内联 ctype 变量?

c++ - Visual C++ 将 char 数组复制到 char 数组

c++ - 计算可以从墙上反弹的球的 future 位置

c++ 代码在 FreeBSD 上没有捕获异常

c++ - 以下划线 (_) 为前缀的类成员

c++ - 避免不必要的负载 (SSE/AVX)