如何从DLL导出C ++类?

时间:2011-07-27 07:03:17

标签: c++ visual-c++ dll

我有一个有两个重载函数的类。如何从dll导出它以及如何使用其他C ++类?我的班级看起来像这样:

#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";
}

4 个答案:

答案 0 :(得分:28)

一种常见的方法是使用一个宏(我们称之为EXPORT),它可以扩展为dllimportdllexport,具体取决于是否某种“立即构建DLL” define设置,如下所示:

#ifdef MAKEDLL
#  define EXPORT __declspec(dllexport)
#else
#  define EXPORT __declspec(dllimport)
#endif

class EXPORT xyz {
  // ...
};

这个想法是在构建DLL时,将MAKEDLL添加到预处理器定义中。这样,所有代码都将被导出。链接到您的DLL(因此包含此头文件)的客户端根本不需要执行任何操作。通过不定义MAKEDLL,他们将自动导入所有代码。

这种方法的优点是,正确获取宏的负担从许多(客户端)转移到DLL的作者。

这样做的缺点是,当按原样使用上面的代码时,不再可能直接将代码编译到某个客户端模块中,因为无法将EXPORT宏定义为空。要实现这一点,您需要另外检查,如果为true,则将EXPORT定义为无。

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

class xyz
{
public: 
    EXPORT void printing();
    EXPORT void printing(int a);
};

答案 1 :(得分:9)

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

我可能错了这个例子(那是很久以前的事),但在这里它应该是如何看起来像:

头文件(.h):

class MyClass { ... };

extern "C" DLL_API MyClass* createMyClass();

源文件(.cpp):

DLL_API MyClass* createMyClass() {
    return new MyClass();
}

编译时定义MY_DLL_EXPORT,请参阅foraidt的答案示例。

答案 2 :(得分:3)

另一个选择:

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

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

属性 - &gt; C / C ++ - &gt;预处理器 - &gt;预处理器定义。

示例:

假设您的项目名称为: MyDLL

该项目的默认宏本地: MYDLL_EXPORTS

 #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 { 
             //.... 
  }

答案 3 :(得分:1)

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

然后在您的图书馆代码中执行以下操作:

#ifdef MY_DLL_EXPORT
#  define DLL_API __declspec(dllexport)
#else
#  define DLL_API __declspec(dllimport)
#endif


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