error dllimport 函数的定义不允许在一个特定的联合中,而其他类、结构和联合将按预期导出

error Definition of dllimport function not allowed at one specific union while other classes, structs and unions get exported as they should

本文关键字:结构 其他 不允许 定义 error dllimport 一个 函数      更新时间:2023-10-16

我正在开发游戏引擎并尝试导出联合,但不知何故不断收到以下错误:

不允许定义 dllimport 函数

现在我知道这个错误意味着什么,并且之前已经解决了它,但在这种情况下,我似乎找不到答案。

我像这样声明dllexport/dllimport:

// Core.h
#ifdef CH_PLATFORM_WINDOWS
#ifdef CH_BUILD_DLL
#define CH_API __declspec(dllexport)
#else 
#define CH_API __declspec(dllimport)
#endif // CH_BUILD_DLL
#else 
#error Cheetah currently only supports windows!
#endif // CH_PLATFORM_WINDOWS

我已经在多个地方使用了这个宏,并且这些类、结构和联合按示例导出/导入

// Vector4.h
#ifndef CHEETAH_ENGINE_MATH_VECTOR4_H_
#define CHEETAH_ENGINE_MATH_VECTOR4_H_
#include "Core/Core.h"
#include "Vector3.h"
namespace cheetah
{
template<typename T>
union CH_API Vector4
{
inline Vector4();
inline Vector4(const T& fill);
inline Vector4(const T fill[4]);
inline Vector4(const Vector3<T>& fill, const T& w);
inline Vector4(const T& x, const T& y, const T& z, const T& w);
struct
{
T x, y, z, w;
};
inline const T* get() const;
inline T magnitude() const;
inline void operator *= (const T& rhs);
inline void operator += (const T& rhs);
inline void operator -= (const T& rhs);
inline void operator /= (const T& rhs);
inline Vector4<T> operator + (const Vector4<T>& rhs) const;
inline Vector4<T> operator - (const Vector4<T>& rhs) const;
inline T operator * (const Vector4<T>& rhs) const;
private:
struct
{
T m_data[4];
};
};
template union CH_API Vector4<float>;
template union CH_API Vector4<int>;
template union CH_API Vector4<double>;
using Vector4f = Vector4<float>;
using Vector4i = Vector4<int>;
using Vector4d = Vector4<double>;
}
#include "Vector4.inl"
#endif // !CHEETAH_ENGINE_MATH_VECTOR_H_

但不知何故,联合四元数没有被导出,即使它与 上面的矢量 4 联合。

// Quaternion.h
#ifndef CHEETAH_CORE_MATH_QUATERNION_H_
#define CHEETAH_CORE_MATH_QUATERNION_H_
#include "Vector4.h"
#include "Vector3.h"
#include "Mat4x4.h"
#include<math.h>
#include "Core/Core.h"
namespace cheetah
{
template<typename T>
union CH_API Quaternion
{
public:
Quaternion();
Quaternion(const T& axisX, const T& axisY, const T& axisZ, const T& degrees);
Quaternion(const Vector3<T>& axis, const T& degrees);
Quaternion(const T fill[4]);
struct
{
T axisX, axisY, axisZ, degrees;
};
inline const T* get() const;
inline Mat4x4<T> getMatrix() const;
inline void normalize();
inline Quaternion<T> normalize(const Quaternion<T>& vector) const;
inline void operator *= (const T& rhs);
inline void operator += (const T& rhs);
inline void operator -= (const T& rhs);
inline void operator /= (const T& rhs);
inline Quaternion<T> operator + (const Vector4<T>& rhs) const;
inline Quaternion<T> operator - (const Vector4<T>& rhs) const;
inline T operator * (const Vector4<T>& rhs) const;
private:
struct 
{
T m_data[4];
};
};
template union CH_API Quaternion<float>;
template union CH_API Quaternion<int>;
template union CH_API Quaternion<double>;
using Quaternionf = Quaternion<float>;
using Quaternioni = Quaternion<int>;
using Quaterniond = Quaternion<double>;
}
#include "Quaternion.inl"
#endif // !CHEETAH_CORE_MATH_QUATERNION_H_

该错误在包含四元数所有实现的实现文件 Quaternion.inl 中的所有四元数联合构造函数上引发。

// Quaternion.inl
namespace cheetah 
{
template<typename T>
inline Quaternion<T>::Quaternion()
: m_data{ 0, 0, 0, 0 }
{
}
template<typename T>
inline Quaternion<T>::Quaternion(const T& axisX, const T& axisY, const T& axisZ, const T& 
degrees)
: m_data{ axisX, axisY, axisZ, degrees }
{
}
template<typename T>
inline Quaternion<T>::Quaternion(const Vector3<T>& axis, const T& degrees)
: m_data{ axis.x, axis.y, axis.z, degrees }
{
}
template<typename T>
inline Quaternion<T>::Quaternion(const T fill[4])
: m_data{ fill[0], fill[1], fill[2], fill[3] }
{
}
}

我没有包括所有实现,因为它有很多行,如果需要更多,请在评论中告诉我。我还转发声明了我想在.cpp文件中导出两个工会的专业。

我看不出向量 4 和四元数并集之间有什么区别,以及为什么 Vector4 被导出而四元数没有。

我尝试过的:

我试图从四元数的 .inl 文件中删除所有类专用化方法,因为这是与 Vector4 联合的少数区别之一,四元数有一些特化成员,如下所示:

template<>
inline void Quaternion<float>::normalize()
{
const float n = 1.0f / sqrt(axisX * axisX + axisY * axisY + axisZ * axisZ + degrees * degrees);
m_data[0] *= n;
m_data[1] *= n;
m_data[2] *= n;
m_data[3] *= n;
}

这仍然会导致错误。

不知何故,CH_API宏不断扩展到 dllimport(也显示在语法突出显示中(,而 Vector4 联合并非如此。

正如评论中所说,联盟不需要用dllexport装饰,通过删除它工作的CH_API宏。我仍然导出模板专用化。

template<typename T>
union CH_API Quaternion

上面的代码需要更改为:

template<typename T>
union Quaternion

然后我可以像这样导出模板专用化:

template union CH_API Quaternion<float>;
template union CH_API Quaternion<int>;
template union CH_API Quaternion<double>;

我无法找出为什么CH_API在这种特定情况下扩展到 dllimport 并使用 Vector4 联合进行 dllexport,如果我发现为什么会发生这种情况,我可能会更新我的答案。