导出 c++ dll class 意外行为

Exporting a c++ dll class unexpected behavoir

我是 c++ 语言的新手,具有广泛的 c# 背景。 我在 visual studio 2022 中设置了一个解决方案,包括一个控制台可执行项目和一个 dll 项目,可执行文件取决于 dll 项目。

dll 依赖于其他一些静态库来最终提供类似 httpclient 的功能。

这些项目是我进一步了解 c++ 的游乐场。 我决定在 exe 和 dll 之间使用类似 c# 的功能,所以我从 dll class MyHttpClient.

导出了一个 class

我的第一个尝试是将 class 作为一个整体导出,但这导致 exe 依赖于 dll 所依赖的某些库,因为 class 具有成员字段,其类型来自这些库,即使构建成功,exe 也会崩溃..

所以我决定在一个单独的干净头文件中创建一个接口 class,其中只有一个 public 构造函数和关键 public 函数;此 class 与完整的 class 具有相同的名称和相同的名称 space,我使用预定义的宏将此摘要 class 修饰为 __declspec(dllexport) __decspec(dllexport/import) class 基于它所在的项目,并将此头文件导入到我的 exe 主文件中。 p.s。请注意完整的 class 也用 __declspec(dllexport).

修饰
//inteface.h
#include "def.h"
//This is the abstract(interface) class
class EXPORT_API MyHttpClient
{
   public:
      MyHttpClient();
      std::string Get();
};

main.cpp 在 exe 中包含 interface.h 文件。

//MyHttpClient.h
//Multiple #include "def.h" ...
class EXPORT_API MyHttpClient
{
   public:
      MyHttpClient();
      std::string Get();
   private:
    // some member fields
};
//MyHttpClient.cpp
provides implementation for the MyHttpClient class

现在是这样:

#include "inteface.h"
int main()
{
// if I declare the class's object on the stack everything works as intended.
  MyHttpClient client;
  auto result = client.Get();

//if I set it on the heap the program crashes with Access violation
// on the private members as if they were not there!!
  HttpClient* cli = new HttpClient;
  auto result = cli->Get(); // crash
...
}

Q1:为什么我会看到这样的行为? 我怀疑 new 运算符调用了抽象 class 的大小并且 因此所有字段都没有分配内存,而堆栈调用 构造器(初始化这些成员的地方)并扩展为这些 成员已初始化(这是我的猜测,但我真的不知道!)。

Q2:如何解决这个问题?

谢谢。

So I decided to make an interface class with only a public constructor and key public functions in a seperate clean headerfile; this class has the same name and inside the same name space as the full class

这违反了 one-definition-rule 并导致您的程序具有未定义的行为。同一个class在不同翻译单元中的定义必须由相同的token序列组成(加上一些额外的要求)

如果你想要一个抽象 class 作为接口,使用继承和(纯)虚函数。