今日はかなり奇妙な問題が発生しました。私はSSE用に最適化された数学ライブラリを持っているため、ほぼすべての機能がインラインとして宣言されています。私はすべての機能を定義するに進みvector3.inlでインライン数学ライブラリをプリコンパイル済みヘッダーファイルと組み合わせて使用するとリンクエラーが発生する
#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は、Vector3.hにこのような何かを宣言されている
:簡素化のために、私は一つのクラス、のVector3を使用して問題を説明します
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
と呼ばれるファイルで私の数学のオブジェクトのすべてが含まれます210
とmath.hは私のプリコンパイルされたヘッダーファイル(プリコンパイルされたh aka stdafx.h)に含まれています
ビルドプロセスから.inlファイルを自動的に除外するVisual Studio 2008を使用します。
これは私が取得していますリンカエラーです:
エラー1つのエラーLNK2005: "パブリック:Virtus社__thiscall ::のVector3 ::のVector3(無効)" (?? 0Vector3 @ヴァータス@@ QAEを@XZ)すでに 私は手動でビルドからすべてのINLファイルを除くように、ほとんどありとあらゆる方法でこれを固定しようとした
precompiled.obj MAIN.OBJ Virtus社で定義されています。プリコンパイルされたファイルにはmath.hを含めず、必要な場所にのみ存在します(この場合、すでに定義済みの同様のリンカーエラーが発生します)。 inl拡張子からcpp拡張子に変更するなどです。私が修正できる唯一の方法は、インクルードガードの代わりに#pragmaを一回使用することでした。だから今回は、あらかじめコンパイルされたヘッダーファイルとガードを組み込んだものとは関係がありますが、これを修正する方法はわかりません。
助けていただければ幸いです!
悪いですが、私はvector3.inlの例にインライン関数の定義を含めませんでした。インライン・キーワードをインプリメンテーション・ファイルに反映させるために投稿を編集しました。 – Millianz
@Millianz: 'inline'は宣言ではなく定義になっています - なぜ私はvector3.inl_の中の定義を変更すると言ったのですか? ; - ] – ildjarn
それを指摘していただきありがとうございます、私はより明確に今参照してください。私の実装には問題がありますが、マイクロソフトのコンパイラはこれを処理できるようです。これはあなたが指摘したように間違っていたとしても、リンクしなかった理由ではありませんでした。主な問題は、ヘッダーにインクルードされたinlファイル内の非インライン関数の実装でした。これにより、複数の定義が発生しました。最終的には本当に明白なことでした:時には、森の木が見えないことがあります:)あなたの助けをありがとう – Millianz