关于visual c ++:如何从dll导出C ++类?

How to export a C++ class from a dll?

本问题已经有最佳答案,请猛点这里访问。

我有一个类,它有两个重载函数。如何从DLL导出它,以及如何通过其他C++类来使用它?我的班级如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#define DECLDIREXP __declspec(dllexport)

#define DECLDIRIMP __declspec(dllimport)


class DECLDIREXP xyz

{

public:
          void printing();
          void printing(int a);
};  

using namespace std;

void xyz::printing()
{
        cout<<"hello i donot take any argument";
}


void xyz::printing(int a)
{
        cout<<"hello i take"<< a <<"as argument";
}


一种常见的方法是有一个单独的宏(我们称之为EXPORT,它可以扩展到dllimportdllexport,这取决于是否设置了某种"立即构建动态链接库"定义,如下所示:

1
2
3
4
5
6
7
8
9
#ifdef MAKEDLL
#  define EXPORT __declspec(dllexport)
#else
#  define EXPORT __declspec(dllimport)
#endif

class EXPORT xyz {
  // ...
};

其思想是,在构建DLL时,将MAKEDLL添加到预处理器定义中。这样,所有代码都将被导出。链接到您的DLL(因此包括这个头文件)的客户机根本不需要做任何事情。如果不定义MAKEDLL,它们将自动导入所有代码。

这种方法的优点是,获得宏权限的负担从许多(客户机)转移到了仅仅是DLL的作者。

这样做的缺点是,当使用上述代码时,由于不可能将EXPORT宏定义为Nothing,因此无法再直接将代码编译到某些客户机模块中。要实现这一点,您需要进行另一个检查,如果为真,则定义导出为零。

关于一个稍有不同的主题:在许多情况下,这是不可能的(或不需要的!)导出这样的完整类。相反,您可能只想导出所需的符号。例如,在您的情况下,您可能只想导出这两个公共方法。这样,不会导出所有私有/受保护的成员:

1
2
3
4
5
6
class xyz
{
public:
    EXPORT void printing();
    EXPORT void printing(int a);
};


我记得,通常情况下,导出的不是类,而是一个工厂函数,它创建类的新实例并返回一个指针。类声明在编译时驻留在头文件中。

关于这个例子(那是很久以前的事了),我可能是错的,但是这里它大概应该是这样的:

头文件(.h):

1
2
3
class MyClass { ... };

extern"C" DLL_API MyClass* createMyClass();

源文件(.cpp):

1
2
3
DLL_API MyClass* createMyClass() {
    return new MyClass();
}

编译时定义我的"dll"导出,请参阅for aidt的回答示例。


彼此选择:

使用项目本地的默认定义宏。

您可以在以下位置看到项目本地定义的默认宏:

属性-> C/C++>预处理器>预处理器定义。

例子:

假设您的项目名称是:mydll

该项目的默认宏:mydll_exports

1
2
3
4
5
6
7
8
9
10
11
12
 #ifdef  MYDLL_EXPORTS
    /*Enabled as"export" while compiling the dll project*/
    #define DLLEXPORT __declspec(dllexport)  
 #else
    /*Enabled as"import" in the Client side for using already created dll file*/
    #define DLLEXPORT __declspec(dllimport)  
 #endif


  class DLLEXPORT  Class_Name {
             //....
  }

在编译库时,应该定义一个宏(命令行预处理器定义),我们称之为MY_DLL_EXPORT

然后在库的代码中执行如下操作:

1
2
3
4
5
6
7
8
#ifdef MY_DLL_EXPORT
#  define DLL_API __declspec(dllexport)
#else
#  define DLL_API __declspec(dllimport)
#endif


class DLL_API some_class { /*...*/ }