将目前为独立可执行文件开发的C ++项目转换为DLL

时间:2011-05-10 17:46:09

标签: c++ visual-studio dll

(我在Windows 7 64位计算机上使用Microsoft Visual Studio 2010)

我开发了一个C ++程序,它更像是一个随着时间的推移变得非常复杂的库。它现在作为一个简单的可执行程序工作,但我想将其转换为DLL,以便其他程序可以轻松访问该功能。

我对使用DLL没有任何经验,但我希望在此过程中避免更多的工作和代码更改。

我知道我可以选择编译目标为“DLL”,但我觉得单独不能完成这项工作。

  • 如果我成功将项目编译成DLL文件,如何在可执行项目中使用其中的函数?

  • 我可以避免使用_dllexport并导入每个名称的每个函数吗?

  • 如何静态链接DLL,以及它的(dis)优势是什么?

4 个答案:

答案 0 :(得分:3)

老实说,我会看看DLL export docs并选择最适合你的导出方法。在任何情况下,您都可以通过客户端应用程序中的名称简单地引用导出的函数,就像使用静态库一样。

当您将项目构建为DLL时,IDE将生成

  1. 运行时的DLL文件和
  2. 包含导出的功能解析信息的LIB文件 - 这是您链接的信息。
  3. 根据定义,您无法静态链接DLL(即 DYNAMIC 链接库) - 而是链接到从DLL导出函数的库,然后在运行时加载DLL,或者自动启动流程或按需启动。也可以在没有任何静态链接的情况下完全按需加载DLL(参见LoadLibraryEx等)。

答案 1 :(得分:2)

由于您使用的是C ++,我假设您正在导出类(?)。 CodeProject上有a really good example个结束,它会引导您完成一些选项。最干净的是使用抽象接口:

  

C ++抽象接口(即只包含纯虚方法而没有数据成员的C ++类)试图充分利用两个世界:一个独立于编译器的对象干净接口,以及一种方便的面向对象的方法调用。所需要做的就是提供带有接口声明的头文件,并实现一个返回新创建的对象实例的工厂函数。只有工厂函数必须使用__declspec(dllexport / dllimport)说明符声明。该接口不需要任何其他说明符。

Example of how the abstract interface example works

您无法静态链接到动态链接库。如果要静态链接,请改为创建.lib。

答案 2 :(得分:1)

  • 要使用您的DLL,您必须#include与您的dll / lib关联的头文件,并链接到与.dll相关联的.lib文件

  • 您需要_ declspec(dllexport)/ _declspec(dllimport)来表示您要导出/导入dll的内容。这可以很容易地完成如下

 #ifdef FOO_EXPORTS
      #define EXPORT_ME __declspec(dllexport)
 #else
      #define IMPORT_ME __declspec(dllimport)
 #endif

在您的dll的标题中,您只需#define FOO_EXPORTS并放置导出

<强> foo.hpp

class EXPORT_ME foo2();

void EXPORT_ME foo_funct(foo2 *foo_ptr);

任何需要使用导出项的文件只需要调用foo.hpp头中定义的方法(默认行为是导入)

<强> use_foo.cpp

main()
{
      #include "foo.cpp";
foo2 myfoo;
foo_funct(&my_foo);
}
  • 正如其他人所说,lib是静态链接的,而dll是动态链接的。静态链接时,任何引用的元素都会在编译时串联放入源中,并且通常会产生更大的程序(就文件大小而言),而动态链接的元素在运行时链接,因此文件大小通常较小。静态与动态还有许多其他优点/缺点 - 我建议您按照Doc Browns链接获取更多信息

答案 3 :(得分:-5)

切换到MinGW下的gcc。构建和链接到DLL就像构建和链接到静态库一样简单。它甚至透明地处理C ++名称修改(但是调用程序也需要用gcc编译)。