2
c:\program files\microsoft visual studio 9.0\vc\include\result.h(212) : warning C4275: non dll-interface class 'std::_Container_base_aux' used as base for dll-interface class 'std::_Container_base_aux_alloc_real<_Alloc>'
1>        with
1>        [
1>            _Alloc=std::allocator<mysqlpp::Row>
1>        ]
1>        C:\Program Files\Microsoft Visual Studio 9.0\VC\include\xutility(377) : see declaration of 'std::_Container_base_aux'

这可能是与容器相关的任何问题的原因,还是可以在 Visual Studio 2008 中安全地忽略?

4

1 回答 1

2

在这种情况下,我认为这取决于 std::runtime_error。为了让客户端使用这个类,它必须使用客户端提供的定义,而不是 DLL 端。为此,客户端编译器应该与 DLL 编译器的版本完全相同。

除了类定义不能跨模块边界移植这一事实之外,还需要考虑内存所有权。

如果你派生自一个具有像 std::string 这样的内部变量的类,那将是一场等待发生的灾难。如果 dll 将使用与另一个类派生自它的应用程序不同的运行时,则可能会发生以下情况:

  • Base 使用文本值初始化字符串。
  • Derived 会尝试更改字符串。
  • 它会尝试释放字符串的堆内存。

这当然不限于字符串。这只是一个例子。任何一个运行时分配某些东西而另一个运行时释放它的情况都会导致崩溃。

堆内存归基类使用的运行时所有。派生类的 Thr 运行时尝试释放它 -> 即时崩溃。为了给您一个使用相同 C++ 编译器编译并使用相同运行时的 dll,您受 dll 提供程序的支配。这是维护的噩梦。

毫无疑问,DLL 类接口是有史以来最糟糕的想法。

仅有的两项豁免是:

  • 您使用 DCOM(或纯抽象类,这是相同的想法)
  • 您可以控制整个代码树。例如,dll 和 exe 构建在同一个解决方案中。

在所有其他情况下,DLL 类接口都支持噩梦和等待发生的灾难。

我认为这个线程 可能会建议你一个解决方案。

/MD如果您使用相同的编译器编译所有内容并使用所有模块共享相同的运行时,请随意忽略 C4275 。

于 2012-12-06T09:26:36.403 回答