【问题标题】:issues with porting a DLL C++ class library to Visual Studio将 DLL C++ 类库移植到 Visual Studio 的问题
【发布时间】:2011-01-02 04:16:45
【问题描述】:

我用 C++ 编写了一个类库,并在 Linux 中以 g++ 作为共享对象成功地编译了它,然后创建了一些使用它的应用程序。现在我必须将它移植到 VS2008。我为所有类提供了所需的 __declspec(dllexport) 前缀,然后尝试编译它。我收到一堆警告,基本上与:

  1. 我的自定义异常类,派生自 std::runtime_error,产生: “警告 C4275:非 dll 接口类 'std::runtime_error' 用作 dll 接口类 'cci::FileOperationException' 的基础”。我应该如何使标准库类 dll 可导出?
  2. 成员函数声明中的异常规范,这会导致“警告 C4290:C++ 异常规范被忽略,除非表明函数不是 __declspec(nothrow)”。我在某处读到 VS 不支持这些,而它在其他地方支持。多么令人困惑。

我读到有人说,在 DLL 中导出类通常是个坏主意,有很多事情可能出错,现在我脑子里充满了诸如二进制不兼容、dll 地狱、编译器版本不匹配等概念,老实说,我无法真正做出正面或反面。那么在 Windows 中创建共享类库的正确、安全和简单的方法是什么?

谢谢。

【问题讨论】:

  • 真的需要DLL吗?制作静态库可以避免很多问题。
  • 好点。 :) 不过,最初的问题仍然存在——人们能够以某种方式使用 DLL,不是吗? (另外,有什么简单的方法可以将构建从共享更改为静态?Project->Properties->General->Configuration Type->Static Library 就足够了吗?)
  • 他们正在使用它们,但并非没有很多箍跳。恕我直言,静态库应该始终是首选。
  • 你用的是什么版本的visual studio?
  • 正如我没有提到的 - 它是 VS2008 Professional。为什么? ;)

标签: c++ visual-studio dll export


【解决方案1】:

我维护a C++ class library,它通常在 Windows 上用作 DLL,因此可以这样做。关于您的问题:

  1. 这不会发生在我的图书馆。也许您需要使用 /MD 和 /MDd 构建选项?这样一来,您的 C++ 运行时库也来自 DLL,这是 VC++ 著名的那种挑剔的东西。

  2. 不要使用 throw-specs。 They are evil。如果您觉得无论如何都必须这样做,只需将这样的内容放在每个模块包含的头文件中,然后再进入使用 throw-specs 的代码。

#pragma 警告(禁用:4290)

【讨论】:

  • 我正在使用 /MD,没有帮助。看完这篇文章,还是把所有的 ES 搞砸了,谢谢。
  • 一般来说,您可能会下载 MySQL++ 并查看其项目设置,以了解为什么我的工作有效而您的无效。 MySQL++ 做了一些类似于你的库的事情:参见 lib/exceptions.h,我们从 std::exception 派生了一个自定义 mysqlpp::Exception 类。
  • 那是因为显然 std::exception is 在微软领域导出。把我的改成它,警告消失了。
  • std::exception 不再在 Microsoft 领域导出 (Visual Studio 2015)
【解决方案2】:

首先你应该问问自己这里是否真的需要一个动态库。静态库,或者甚至更好地将源代码直接包含在您的项目中是一个没有这些问题的好解决方案。

如果您真的需要 DLL,我会这样做(给定很多时间)的方法是将您的类包装在 C 接口中。然后,您可以将旧的 C++ 接口重新创建为仅与从 DLL 导出的 C 调用交互的 C++ 标头库。这种方法的一个额外功能是,几乎可以从任何编程语言中使用您的库,因为高度支持从 DLL 导入 C 函数。

另一种方法是使用 COM,但由于您是从 Linux 移植,这可能不是一个选项。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-27
    • 1970-01-01
    • 2012-08-15
    • 2012-01-22
    • 1970-01-01
    相关资源
    最近更新 更多