我们可以忽略 MySQL++ C4275 警告?

发布于 2024-09-25 01:31:19 字数 551 浏览 2 评论 0原文

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 中安全地忽略它吗?

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'

Can that be cause of any problems related to containers or can it safely be ignored in Visual Studio 2008?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

冷月断魂刀 2024-10-02 01:31:19

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

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

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

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

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

堆内存由基类使用的运行时拥有。派生类的运行时尝试释放它 ->瞬间崩溃。为了给你一个用相同的 C++ 编译器编译并使用相同的运行时的 dll,你必须受到 dll 提供者的摆布。这是维护的噩梦。

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

唯一的 2 个例外是:

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

在所有其他情况下,DLL 类接口都是支持噩梦,并且灾难即将发生。

我认为 此主题
可能会建议您一个解决方案。

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

In this case, I think it depends on std::runtime_error. For the client to use this class it must use the definition as provided on the client side, not the DLL side. For this to succeed the client compiler should be exactly the same version as the DLL compiler.

And apart from the fact that class definitions are not portable across module boundaries, there is also the memory ownership to consider.

If you derive from a class that has an internal variable like a std::string, it would be a disaster waiting to happen. If the dll would use a different runtime from the application in which another class derives from it, the following could happen:

  • Base initializes the string with a text value.
  • Derived would try to change the string.
  • It would try to release the heap memory of the string.

This is not limited to strings of course. It was just an example. Any scenario where 1 runtime allocates something and another deallocates it will result in a crash.

The heap memory is owned by the runtime that is used by the base class. Thr runtime of the derived class tries to release it -> instant crash. You are at the mercy of the dll provider in order to give you a dll that is compiled with the same C++ compiler, and uses the same runtime. This is a maintenance nightmare.

DLL class interfaces are without a doubt the worst idea ever.

The only 2 exemptions are:

  • you use DCOM (or pure abstract classes, which is the same idea)
  • you are in control of the entire code tree. For example the dll and the exe are built in the same solution.

In all other cases, DLL class interfaces are support nightmares, and disasters waiting to happen.

I think this thread
can possibly suggest you a solution.

Feel free to ignore C4275 if you compile everything with the same compiler and use /MD so all modules share the same runtime.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文