0

[编辑:进一步挖掘揭示了一个不同的根本问题。我正在重新表述这个问题,但为了与@Leo 的回答保持一致,将旧版本留在下面]

似乎 VC++(在 VS2005 和 VS2010 下)允许我 dllexport 缺少实现的类!以下代码构建良好:

// missingimp.h :
class __declspec(dllexport) MissingImp
{
  void DoStuff();   // no implementation anywhere
  void DoMoreStuff();  // neither for this
}

// missingimp.cpp
#include "missingimp.h"

代码编译和链接都很好(在 dll 配置中) - 当然与生成的 dll 静态链接失败。这是一个错误吗?这种行为是设计使然吗?

[老问题:]

我正在尝试 dllexport 一个类,该类具有在前向声明的类型上模板化的数据成员:

// Class2Export.h:

class ForwardDeclared ;

template<class T> class TemplatedClass
{
T *m_ptr;

public:
TemplatedClass() { m_ptr->DoSomething(); }

};

class __declspec(dllexport) ExportedClass
{
TemplatedClass<ForwardDeclared> TemplateForward;
};

// Class2Export.cpp:

#include "Class2Export.h"

(这不是一个人为的例子——在实际代码中 TemplatedClass 是一个智能指针,但这似乎与手头的问题无关。)

此代码无法编译,使用 -

错误 C2027:使用未定义类型“ForwardDeclared”

根据MS 的回复,这仍然具有某种意义:

如果 TemplatedClass 有构造函数,那么将自动为 ExportedClass 生成构造函数。由于 ExportedClass 已导出,编译器尝试导出构造函数,但无法为其生成代码,因为 ForwardDeclared 是未知的。

但我怀疑这不是最终答案,因为当我为 ExportedClass 声明(甚至没有实现!)一个 ctor 时:

...
class __declspec(dllexport) ExportedClass
{
ExportedClass();
TemplatedClass<ForwardDeclared> TemplateForward;
};
...

编译和链接都成功(带有适当的警告*)。MS-connect 上的问题似乎已被放弃 - 也许任何人都可以对这种奇怪的行为有所了解?

谢谢!

*编辑:生成的警告是C4251:类 'TemplatedClass' 需要有 dll 接口才能被类 'ExportedClass' 的客户端使用

4

2 回答 2

1

除非我搞错了,否则问题在于何时生成 ExportedClass 构造函数代码。

如果在声明 ForwardDeclared 之前生成 ExportedClass 构造函数代码(不是前向声明而是正确声明),那么您将收到错误,因为 ExportedClass 构造函数隐式调用 TemplatedClass 构造函数,并且调用未定义的 ForwardDeclared 方法。

您的最后一个示例,即编译并带有警告链接的示例,因为从未定义 ExportedClass 构造函数而起作用。(可能警告是 ExportedClass::ExportedClass 不存在。因为实际上没有任何尝试使用它,所以它只是一个警告而不是错误。)你已经避免了那里的问题。实际上,该代码没有用,因为没有任何东西可以创建 ExportedClass (它没有构造函数),但是如果您在某处定义构造函数,那么一切都应该正常工作,前提是在此之前声明/定义了 ForwardDeclared。

如果您将最后一个示例更改为此,您应该再次获得错误:(添加的只是两个大括号,为 ExportedClass 构造函数提供一个空主体)

class __declspec(dllexport) ExportedClass
{
    ExportedClass() { } // Error here
    TemplatedClass<ForwardDeclared> TemplateForward;
};

如果您根本没有 ExportedClass 的构造函数,那么该代码就是您隐式执行的操作。在这些情况下,构造函数的代码在此处生成,然后在头文件中生成。另一方面,当在标头中声明构造函数时没有正文时,您将代码留待在其他地方定义和生成。

于 2011-01-06T16:41:24.003 回答
0

最终我在 MS 论坛中找到了答案。

我在这里链接到它,以防有一天它对任何人有用。

于 2011-01-16T07:10:22.427 回答